另一个多对多并发症 - Entity Framework 4.1 DbContext

时间:2011-10-13 18:36:02

标签: entity-framework entity-framework-4.1 many-to-many dbcontext

我正在使用DB第一种方法,EF 4.1使用DbContext POCO代码生成。

我的数据库具有多对多关系,如下所示:

员工

EMPLOYEEID

EmployeeName

帐户

ACCOUNTID

帐户名

EmployeeAccount

EMPLOYEEID

ACCOUNTID

当我尝试更新员工并将其帐户分配更改为预先存在的帐户时,会出现问题,因此我基本上按以下方式执行此操作:

using(context)
{
  var query = from e in context.Employees.Include(f => f.Accounts)
              where e.EmployeeId == employeeId
              select;

  Employee emp = query.FirstOrDefault()
}

emp.EmployeeName = "Test";

emp.Accounts.Clear();

Account act = MethodThatLooksUpAccountByName("SomeAccountName");

emp.Accounts.Add(act);

using(context)
{
  context.Accounts.Attach(act);

  emp.State = EntityState.Modified;

  context.Employees.Attach(emp);

  context.SaveChanges();
}

正在生成的SQL正在[Employee]表上执行更新,根本没有[EmployeeAccount],没有删除没有插入。

1 个答案:

答案 0 :(得分:1)

尝试删除(至少)最后一个Attach。您也不需要将状态设置为Modified,因为您处于附加方案中(emp从DB加载)并且更改跟踪将识别更改内容:

var query = from e in context.Employees.Include(f => f.Accounts)
            where e.EmployeeId == employeeId
            select;
Employee emp = query.FirstOrDefault()

emp.EmployeeName = "Test";
emp.Accounts.Clear();

Account act = MethodThatLooksUpAccountByName("SomeAccountName");
// next line is only necessary if MethodThatLooksUpAccountByName
// uses another context. If it uses the same context you can remove this line.
context.Accounts.Attach(act); 

emp.Accounts.Add(act);

context.SaveChanges();

这在我看来应该有用。

更改问题中的代码后,

编辑

第二个上下文执行自己的更改跟踪。因此,它无法识别您已删除帐户并添加了新帐户。它应该按以下方式工作:

using(...context...)
{
    var query = from e in context.Employees.Include(f => f.Accounts)
                where e.EmployeeId == employeeId
                select;

    Employee emp = query.FirstOrDefault()
}

Account act = MethodThatLooksUpAccountByName("SomeAccountName");

using(...context...)
{
    context.Employees.Attach(emp);
    context.Accounts.Attach(act);

    emp.EmployeeName = "Test";
    emp.Accounts.Clear();
    emp.Accounts.Add(act);

    context.SaveChanges();
}

我有这种感觉,这不是你想要的。您是否在与上一个上下文分离的状态下完成了员工的更改(清除旧帐户并添加新帐户)? 多对多集合的问题在于必须在要清除或更改它的上下文中加载或附加旧Account集合。通过设置任何标量属性或在任何实体上设置状态,无法在链接表上触发任何DELETE或INSERT语句。只检测集合中的更改,EF才会更新链接表。