2012-07-25 95 views
10

我有以下实体框架代码第一个代码。表格被创建并且数据被插入。但俱乐部表中有重复的记录。实体框架:多对多关系中的重复记录

我的操作是: -

  1. 使用俱乐部创建应用

  2. 使用人应用

如何避免重复条目

创建者创建的俱乐部?

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 2012-07-25 09:10:52

+0

@ podiluska。不,我只跑了一次。 – Lijo 2012-07-25 09:11:45

回答

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上下文我的操作。

+0

查看我的编辑和代码示例 – 2012-07-25 10:01:58

+0

在该代码示例中,只有一个EF上下文。我需要单独的EF上下文。有什么想法吗? – Lijo 2012-07-25 10:15:33

+1

如果你想使用来自不同源的实体,那么你需要附加它们:http://msdn.microsoft.com/en-us/library/bb896271.aspx – 2012-07-25 10:19:06

0

由于@PeterPorfy

而且读Exception of type 'System.ObjectDisposedException'

我用

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

用于从先前上下文安装的对象。

我使用的IEntityWithKey的一个例子如下。如果您发现此方法存在任何问题,请发表评论。

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

    public EntityKey EntityKey { get; set; } 
} 

请参考下面还

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

+0

对于那些downvote - 我感兴趣看看为什么有一个downvote。这个答案有什么问题吗? – Lijo 2013-09-09 05:38:41

+0

我想他们更喜欢彼得的答案被标记为正确的答案。只是说。 – Miro 2014-07-31 12:46:00

+0

我没有downvoted。 – Miro 2014-07-31 15:28:43