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

mrt*_*rtx 6 c# entity-framework ef-code-first entity-framework-4.3

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

我定义了以下类:

public abstract class Entity
{
    [Column(Order = 0)]
    [Key]
    public int Id { get; set; }

    [Timestamp]
    [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<Coworker> Coworkers { get; set; }
}


public class Coworker : Entity
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual ICollection<Video> Videos { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

创建数据库时,架构看起来正确:还有一个视频,同事和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<T>().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<T>().Attach(entity);
        session.Context.Entry(entity).State = EntityState.Modified;
    }
    return entity;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

Sla*_*uma 6

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

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

using (var session = new DatabaseSession())
{
    video2 = session.Context.Set<Video>().Include(v => v.Coworkers)
        .Single(v => v.Id == video2Id);

    coworkerA = new Coworker { Id = coworkerAId };
    session.Context.Set<Coworker>().Attach(coworkerA);

    video2.Coworkers.Clear();
    video2.Coworkers.Add(coworkerA)

    session.Context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

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


Tas*_*que -1

请参考这里 首先了解如何在 ASP.NET MVC 中使用数据库保存主详细信息。希望它能让您首先了解代码。您还可以查看knokout.js示例