entity framework:多对多关系中的重复记录
我有以下entity framework代码的第一个代码。 创建表并插入数据。 但是俱乐部表中有重复的记录。
我的业务是: –
-
使用俱乐部创建应用创建俱乐部
-
使用person app创建人员
如何避免重复输入?
static void Main(string[] args) { Database.SetInitializer(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 clubsForPerson1 = new List(); clubsForPerson1.Add(club1); clubsForPerson1.Add(club3); List clubsForPerson2 = new List(); 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 Clubs { get; set; } } public class Club { public int ClubId { get; set; } public string ClubName { get; set; } public virtual ICollection 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(); } public DbSet Persons { get; set; } public DbSet Clubs { get; set; } }
问题是你创建了更多的上下文。
首先你创建俱乐部。 没关系。 但是当你创建这些人时,你会通过GetClubs
获取俱乐部,但是对于每个俱乐部,你都会处理实际的entity framework上下文,这样你最终会得到分离的实体。 在InsertPersons
您可以向新人添加分离的俱乐部实体,因此实际情况会认为俱乐部是新的俱乐部。
因此,当您向某个人添加一个俱乐部时,您实际上会创建新的俱乐部
这是因为entity framework跟踪变化并管理每个上下文的实体。 如果您将实体添加到尚未包含它的上下文中,那么它将被视为新实体。
实际上,你应该做这样的事情(未经测试):
static void Main(string[] args) { Database.SetInitializer(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 clubsForPerson1 = new List (); clubsForPerson1.Add(club1); clubsForPerson1.Add(club3); List clubsForPerson2 = new List (); 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
另请阅读“System.ObjectDisposedException”类型的exception
我用了
((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; } }
请参阅以下内容
- SaveChanges()Entity Framework 4.1的问题
- entity framework更新多对多关系 – POCO