2012-07-25 25 views
10

次のエンティティフレームワークコードの最初のコードがあります。テーブルが作成され、データが挿入されます。しかし、クラブテーブルには重複したレコードがあります。Entity Framework:多対多関係の重複レコード

私の操作は次のとおりです。 -

  1. は、クラブ作成アプリどのように重複したエントリを回避する人物のアプリ

を使用して

  • 作成者使用してクラブを作成しますか?

    enter image description here

    static void Main(string[] args) 
        { 
         Database.SetInitializer<NerdDinners>(new MyInitializer()); 
    
         CreateClubs(); 
         InsertPersons(); 
    
        } 
    
        public static void CreateClubs() 
        { 
    
         string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
         using (var db = new NerdDinners(connectionstring)) 
         { 
    
          Club club1 = new Club(); 
          club1.ClubName = "club1"; 
    
          Club club2 = new Club(); 
          club2.ClubName = "club2"; 
    
          Club club3 = new Club(); 
          club3.ClubName = "club3"; 
    
          db.Clubs.Add(club1); 
          db.Clubs.Add(club2); 
          db.Clubs.Add(club3); 
    
          int recordsAffected = db.SaveChanges(); 
    
    
         } 
        } 
    
        public static Club GetClubs(string clubName) 
        { 
         string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
         using (var db = new NerdDinners(connectionstring)) 
         { 
    
          //var query = db.Clubs.Where(p => p.ClubName == clubName); 
          var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName); 
          return query; 
         } 
        } 
    
        public static void InsertPersons() 
        { 
         string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
         using (var db = new NerdDinners(connectionstring)) 
         { 
    
          Club club1 = GetClubs("club1"); 
          Club club2 = GetClubs("club2"); 
          Club club3 = GetClubs("club3"); 
    
          Person p1 = new Person(); 
          p1.PersonName = "Person1"; 
    
          Person p2 = new Person(); 
          p2.PersonName = "Person2"; 
    
          List<Club> clubsForPerson1 = new List<Club>(); 
          clubsForPerson1.Add(club1); 
          clubsForPerson1.Add(club3); 
    
          List<Club> clubsForPerson2 = new List<Club>(); 
          clubsForPerson2.Add(club2); 
          clubsForPerson2.Add(club3); 
    
          p1.Clubs = clubsForPerson1; 
          p2.Clubs = clubsForPerson2; 
    
          db.Persons.Add(p1); 
          db.Persons.Add(p2); 
    
          int recordsAffected = db.SaveChanges(); 
    
    
         } 
        } 
    

    ドメイン

    public class Person 
    { 
        public int PersonId { get; set; } 
        public string PersonName { get; set; } 
        public virtual ICollection<Club> Clubs { get; set; } 
    } 
    
    public class Club 
    { 
        public int ClubId { get; set; } 
        public string ClubName { get; set; } 
        public virtual ICollection<Person> Members { get; set; } 
    } 
    
    //System.Data.Entity.DbContext is from EntityFramework.dll 
    public class NerdDinners : System.Data.Entity.DbContext 
    { 
    
        public NerdDinners(string connString): base(connString) 
        { 
    
        } 
    
        protected override void OnModelCreating(DbModelBuilder modelbuilder) 
        { 
         //Fluent API - Plural Removal 
         modelbuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
        } 
    
        public DbSet<Person> Persons { get; set; } 
        public DbSet<Club> Clubs { get; set; } 
    
    } 
    
  • +1

    も以下を参照してください? – podiluska

    +0

    @ podiluska。いいえ、私は一度だけ走った。 – Lijo

    答えて

    18

    問題は、あなたがより多くのコンテキストを作成することです。

    まず、クラブを作成します。大丈夫です。しかし、人を作成するときには、GetClubsでクラブを取得しますが、各クラブごとに実際のエンティティ・フレームワーク・コンテキストを破棄して、分離されたエンティティになります。 InsertPersonsには、離脱したクラブエンティティを新しい人物に追加するので、実際の状況ではクラブが新しい​​クラブであると考えられます。

    だから、あなたが実際に新しいクラブを作る人にクラブを追加するとき。

    これは、エンティティフレームワークが変更を追跡し、コンテキストごとにエンティティを管理するためです。エンティティをまだ含んでいないコンテキストにエンティティを追加すると、エンティティは新しいエンティティのように扱われます。もちろん

    static void Main(string[] args) 
    { 
        Database.SetInitializer<NerdDinners>(new MyInitializer()); 
    
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30"; 
        using (var db = new NerdDinners(connectionstring)) 
        { 
         CreateClubs(db); 
         InsertPersons(db); 
        } 
    
    } 
    
    public static void CreateClubs(NerdDinners db) 
    { 
        Club club1 = new Club(); 
        club1.ClubName = "club1"; 
    
        Club club2 = new Club(); 
        club2.ClubName = "club2"; 
    
        Club club3 = new Club(); 
        club3.ClubName = "club3"; 
    
        db.Clubs.Add(club1); 
        db.Clubs.Add(club2); 
        db.Clubs.Add(club3); 
    
        int recordsAffected = db.SaveChanges(); 
    } 
    
    public static Club GetClubs(string clubName, NerdDinners db) 
    { 
        //var query = db.Clubs.Where(p => p.ClubName == clubName); 
        var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName); 
        return query; 
    } 
    
    public static void InsertPersons(NerdDinners db) 
    { 
        Club club1 = GetClubs("club1", db); 
        Club club2 = GetClubs("club2", db); 
        Club club3 = GetClubs("club3", db); 
    
        Person p1 = new Person(); 
        p1.PersonName = "Person1"; 
    
        Person p2 = new Person(); 
        p2.PersonName = "Person2"; 
    
        List<Club> clubsForPerson1 = new List<Club>(); 
        clubsForPerson1.Add(club1); 
        clubsForPerson1.Add(club3); 
    
        List<Club> clubsForPerson2 = new List<Club>(); 
        clubsForPerson2.Add(club2); 
        clubsForPerson2.Add(club3); 
    
        p1.Clubs = clubsForPerson1; 
        p2.Clubs = clubsForPerson2; 
    
        db.Persons.Add(p1); 
        db.Persons.Add(p2); 
    
        int recordsAffected = db.SaveChanges(); 
    } 
    

    あなたは、このコードの構造をリファクタリングが、私は私の操作のための唯一のEFコンテキストを使用することに注意してくださいする必要があります

    実際には、この(テストしていない)のような何かを行う必要があります。 @PeterPorfy

    +0

    私の編集とコードサンプルを参照してください –

    +0

    そのコードサンプルでは、​​EFコンテキストは1つのみです。私は別々のEFの文脈が必要です。何かご意見は? – Lijo

    +1

    実際のコンテキストとは異なるソースのエンティティを使用する場合は、それらを添付する必要があります。http://msdn.microsoft.com/en-us/library/bb896271.aspx –

    0

    おかげでまた、私は前のコンテキストからオブジェクトを取り付けるため

    ((IObjectContextAdapter)db).ObjectContext.Attach((IEntityWithKey)entity); 
    

    を使用Exception of type 'System.ObjectDisposedException'

    をお読みください。

    私が使用したIEntityWithKeyの1つの例は次のとおりです。この方法に問題がある場合はコメントしてください。

    public class Person : IEntityWithKey 
    { 
        public int PersonId { get; set; } 
        public string PersonName { get; set; } 
    
        public EntityKey EntityKey { get; set; } 
    } 
    

    あなたはそれを2回実行しました

    1. Problem with SaveChanges() Entity Framework 4.1
    2. Entity Framework Updating Many-To-Many Relationships - POCO

    +0

    downvoteについて - 私は興味がありますなぜdownvoteがあるか見ることができます。この答えに何か問題はありますか? – Lijo

    +0

    私は彼らがピーターの答えを正しいものとしてマークすることを好むと思います。ただ言って。 – Miro

    +0

    私はdownvotedしていません。 – Miro

    関連する問題