无法更新Entity Framework中的多对多关系

我正在使用Entity Framework 4.3 Code First,我在更新多对多关系方面遇到了问题。

我定义了以下类:

public abstract class Entity { [Column(Order = 0)] [Key] public int Id { get; set; } 1541642903 [Column(Order = 1)] public byte[] Version { get; set; } } public class Video : Entity { public string Title { get; set; } public string Description { get; set; } public TimeSpan Length { get; set; } public virtual ICollection Coworkers { get; set; } } public class Coworker : Entity { public string FirstName { get; set; } public string LastName { get; set; } public virtual ICollection 

创建数据库时,架构看起来正确:还有一个video,同事和VideoCoworkers表,没有

我在N层应用程序中使用存储库模式来访问数据库,我的Insert和Update方法如下所示:

 public T Insert(T entity) { //Creates database context. When it disposes, it calls context.SaveChanges() using (var session = new DatabaseSession()) { session.Context.Set().Add(entity); } } public T Update(T entity) { //Creates database context. When it disposes, it calls context.SaveChanges() using (var session = new DatabaseSession()) { entity = session.Context.Set().Attach(entity); session.Context.Entry(entity).State = EntityState.Modified; } return entity; } 

当我更新实体时,我从DTO创建实体对象,这就是使用DbSet.Attach而不是选择它并逐个更新属性的原因。

当我初始化数据库时,我添加了一些测试数据:

  1. 创建3个同事,我设置名字和姓氏。 (A,B,C)
  2. 创建3个video,我设置标题,描述和长度,并设置一些同事。 第一个video有A,B,第二个有B,C,第三个有A,C。

当我从代码中列出video时,我可以看到Video.Coworkers集合中充满了良好的值,当我在SQL Server Management Studio中查询链接表(VideoCoworkers)时,它看起来也很不错。

我的问题是当我更新例如video的标题时,它的工作原理。 但是当我尝试从Video2中删除现有的同事(B和C),并尝试添加同事A时,则关系不会更新。 当我只尝试添加新的同事,或者只尝试删除一个时,它也不起作用。 我创建了一个实体,它用作Update()方法的参数,方法是创建一个新的Video实体,该实体包含一个新的Coworkers集合(使用Id的Find()方法从数据库中选择)。

更新多对多关系的正确方法是什么?

但是当我尝试从Video2中删除现有的同事(B和C),并尝试添加同事A时,则关系不会更新。

不使用通用存储库,正确的过程将是:

 using (var session = new DatabaseSession()) { video2 = session.Context.Set 

必要的部分是您必须以实际状态加载或附加实体,更改实体,即删除和添加子项,然后保存更改。 EF的更改检测将为链接表条目创建必要的INSERT和DELETE语句。 在您的通用Update方法中尝试将状态设置为Modified的简单过程仅适用于更新标量属性(如更改video标题),但不适用于更新实体之间的关系。

为了解决这个问题:

  1. 将实体附加到上下文
  2. 加载集合(未加载集合,因为)
  3. 将实体的状态更改为已修改
  4. 保存更改

所以你的更新代码应该是这样的:

 public Video Update(Video entity) { //Creates database context. When it disposes, it calls context.SaveChanges() using (var session = new DatabaseSession()) { entity = session.Context.Set 

请参考这里 ,了解如何首先在数据库中保存asp.net mvc中的主要细节。 希望它能首先给你关于代码的想法。 你也可以看看knokout.js的例子