2013-10-28 17 views
19

私はいつもOne to OneまたはOne to Manyにマッピングしているため、多対多の関係を作成してEFでテストします。試してみるために、例では、インサート・レジスタのために働いているが、私は、レジスタエンティティフレームワークコードの多対多の関係を最初にマッピングする

を読み取ることができません。ここに私のクラスで、私はHashSetあるかわからない、私はサイト

public class Person 
{ 
    public int PersonId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public ICollection<Course> CoursesAttending { get; set; } 

    public Person() 
    { 
     CoursesAttending = new HashSet<Course>(); 
    } 
} 

public class Course 
{ 
    public int CourseId { get; set; } 
    public string Title { get; set; } 

    public ICollection<Person> Students { get; set; } 

    public Course() 
    { 
     Students = new HashSet<Person>(); 
    } 
} 

にこのコードを取得しますここに私の状況です

public class SchoolContext : DbContext 
{ 
    public DbSet<Course> Courses { get; set; } 
    public DbSet<Person> People { get; set; } 

    public SchoolContext() 
     : base("MyDb") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Course>(). 
      HasMany(c => c.Students). 
      WithMany(p => p.CoursesAttending). 
      Map(
       m => 
       { 
        m.MapLeftKey("CourseId"); 
        m.MapRightKey("PersonId"); 
        m.ToTable("PersonCourses"); 
       }); 

    } 
} 

私はレジスタを挿入し、右

static void Main(string[] args) 
{ 
    using (SchoolContext db = new SchoolContext()) 
    { 
     Course math = new Course(); 
     Course history = new Course(); 
     Course biology = new Course(); 
     math.Title = "Math"; 
     history.Title = "History"; 
     biology.Title = "Biology"; 

     db.Courses.Add(math); 
     db.Courses.Add(history); 
     db.Courses.Add(biology); 

     Person john = new Person(); 
     john.FirstName = "John"; 
     john.LastName = "Paul"; 
     john.CoursesAttending.Add(history); 
     john.CoursesAttending.Add(biology); 

     db.People.Add(john); 
     db.SaveChanges(); 
    } 
} 

あるしかし、私はショーのコンテンツの選択レジスタをしようとすると、動作していない、それはちょうど私がデータベースにチェックしていた何も

static void Main(string[] args) 
{ 
    using (SchoolContext db = new SchoolContext()) 
    { 
     Pearson p = db.Peasons.First(); 
     Console.WriteLine(p.CoursesAttending.First().Title); 
    } 
} 

を印刷していない、レジスタは、存在します何が問題ですか?

最初にコードとの関係を多く選択する方法を教えてください。

+0

多対多リレーションシップのナビゲーションプロパティで '.Add()'を使用すると、EFは自動的に対応するジョイントテーブルを更新しますか? – Celdor

+0

@Celdor EFは、対応する結合表を更新します。 – IFink

答えて

33

まず第一に、あなたはコレクション仮想を行うことで遅延読み込みを有効にすることができます:

public virtual ICollection<Course> CoursesAttending { get; set; } 
public virtual ICollection<Person> Students { get; set; } 

これは、EFはCourseとしてコレクションを上書きPersonから派生したクラス(プロキシ)を作成することができますデータストアからデータをロードするロジック。

あなたが

Console.WriteLine(p.CoursesAttending.First().Title); 

CoursesAttendingを移入するために別のクエリを実行することが表示されますことを行います。

代わりに、またはそれに加えて、あなたはとても似熱心ロードして、データベースへのラウンドトリップを防ぐために決めることができる:1回のショットでPersonCoursesAttendingをロード

Person p = db.Persons.Include(p => p.CoursesAttending).First(); 

を。

+0

素晴らしい!それは仕事です!だから...インクルードはなぜ高速選択に使用していますか?私は使用方法を理解していません – Lai32290

+1

言葉のように、 'Include'はクエリにプロパティを含みます。通常、オブジェクトを取得して後で別のクエリで関連オブジェクトをクエリするよりも、(結合を使用して)1つのSQLクエリを持つ方が効率的です。 –

-1

クラスコンストラクターとそのOnModelCreatingメソッドを削除します。 EFは多対多の関係を処理します。余計なことをする必要はありません。

+6

データアノテーションを使用すると、デフォルトでファンキーな命名規則が得られ、流暢なAPIコードを提供することで、このような望ましくない命名を避けることができます。 –

+0

この回答はIMOのOTであり、まったく役に立ちません。 – Celdor

関連する問題