1 public class Area
2{3 public int Id { get; set;}4 public int AreaName { get; set;}5}
Modelの全体は以下の様に定義してあります。
C#
1using System.ComponentModel.DataAnnotations;2using System.Data.Entity;34namespace ForumMVC.Models.Forum
5{6 class ForumModels
7{8}910 public class Area
11{12 public int Id { get; set;}13 public int AreaName { get; set;}14}1516 public class Topic
17{18 public int Id { get; set;}19[Required]20[Display(Name ="地域")]21 public int AreaId { get; set;}22[Required]23[Display(Name ="カテゴリー")]24 public int CategoryId { get; set;}25[Required]26[Display(Name ="タイトル")]27 public string Title { get; set;}28[Required]29[Display(Name ="本文")]30 public string Contents { get; set;}31[Required]32[Display(Name ="ユーザー名")]33 public int TopicOwnerId { get; set;}34}3536 public class ForumConnection : DbContext
37{38 public DbSet<Topic> Topics { get; set;}39}40}
データベースに「トピックス」「地域」「カテゴリー」「ユーザー」と言うテーブルを作る必要があるはずですが、それらはどうなってますか? 今のコードを見ると EF Code First で作るにしても「トピックス」テーブルしか生成されないように見えますが? 追加するとして、ナビゲーションプロパティはどうしますか?
それをベースに Visual Studio で Entity Data Model を生成すると(方法は上に紹介した記事を読んでください)、以下のコンテキストクラスとターブルクラスが生成されます。Products.cs の中のナビゲーションプロパティ Categoties, Suppliers に注目してください。
NorthwindEdm.Context.cs
namespace Mvc5App
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class NORTHWINDEntities : DbContext
{
public NORTHWINDEntities()
: base("name=NORTHWINDEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<AspNet_SqlCacheTablesForChangeNotification> AspNet_SqlCacheTablesForChangeNotification { get; set; }
public virtual DbSet<Categories> Categories { get; set; }
public virtual DbSet<CustomerDemographics> CustomerDemographics { get; set; }
public virtual DbSet<Customers> Customers { get; set; }
public virtual DbSet<Employees> Employees { get; set; }
public virtual DbSet<Order_Details> Order_Details { get; set; }
public virtual DbSet<Orders> Orders { get; set; }
public virtual DbSet<Products> Products { get; set; }
public virtual DbSet<Region> Region { get; set; }
public virtual DbSet<Shippers> Shippers { get; set; }
public virtual DbSet<Suppliers> Suppliers { get; set; }
public virtual DbSet<Territories> Territories { get; set; }
}
}
Products.cs
namespace Mvc5App
{
using System;
using System.Collections.Generic;
public partial class Products
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Products()
{
this.Order_Details = new HashSet<Order_Details>();
}
public int ProductID { get; set; }
public string ProductName { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<int> CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
public Nullable<short> ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public virtual Categories Categories { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Order_Details> Order_Details { get; set; }
public virtual Suppliers Suppliers { get; set; }
}
}
Categories.cs
namespace Mvc5App
{
using System;
using System.Collections.Generic;
public partial class Categories
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Categories()
{
this.Products = new HashSet<Products>();
}
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public byte[] Picture { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Products> Products { get; set; }
}
}
Suppliers.cs
namespace Mvc5App
{
using System;
using System.Collections.Generic;
public partial class Shippers
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Shippers()
{
this.Orders = new HashSet<Orders>();
}
public int ShipperID { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Orders> Orders { get; set; }
}
}
上の Entity Data Model をベースにスキャフォールディング機能を利用して Controller と View を生成すれば、自力では一行もコードを書かずに望むことができるはずです。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Mvc5App;
namespace Mvc5App.Controllers
{
public class ProductsController : Controller
{
private NORTHWINDEntities db = new NORTHWINDEntities();
// GET: Products
public ActionResult Index()
{
var products = db.Products.Include(p => p.Categories).Include(p => p.Suppliers);
return View(products.ToList());
}
}
}
上の回答にも書きましたが、virtual キーワードのついている Categoties, Suppliers がナビゲーションプロパティです。
DB First で、既存の DB の外部キー制約の付与されているテーブルをベースに EDM を生成すると、自動的にコードにナビゲーションプロパティが含まれるようになります。
逆に、Code First でナビゲーションプロパティを定義して DB を生成すると、生成される DB のテーブルに定義に従って外部キー制約が付与されます。
外部キー制約は SQL Server などの DB の、ナビゲーションプロパティは Entity Framework の基本のキに近いことですので、ググるなどすれば十分な情報は得られると思いますので調べてみてください。
データーベースが基になっているようですので、最初にデータベースの構造をきちんと設計するところから話を始めるべきだと思います。きちんとできていれば、DB First でも Code First でもナビゲーションプロパティが定義されるはずですので、それを使って取得するのが、ASP.NET MVC + Linq to Entiries では普通のやりかたです。(だから上のコメントで質問しているのですが)
質問者さんの過去スレッドを見ると初学者の方のようですので、まずは ASP.NET MVC でごく一般的な方法をベースに話を進めるべきだと思います。でないと、ミスリードすることになるかもしれません。
そもそも、どこにどのような形で必要な情報を保持しておくか、それからどのように取得するかは提案されてないようですが、それはどうするつもりだったのでしょう? DB 以外に適当&現実的な場所があるのでしょうか?