1

我使用DB第一方法,EF 4.1與DbContext POCO代碼gen。另一個多對多的複雜性 - 實體框架4.1 DbContext

我的數據庫有許多一對多的關係如下圖所示:

員工

僱員

EmployeeName

帳戶

ACCOUNTID

帳戶名

EmployeeAccount

僱員

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

嘗試移除(至少)最後一個Attach。你也不需要狀態設置爲Modified因爲你是一個附加的方案(emp從數據庫加載)和變更跟蹤將認識到什麼的確發生了變化:

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纔會更新鏈接表。

+0

我的歉意,我沒有正確表示情況。我不在附加場景中,因爲上下文在linq語句之後放置。查看編輯的問題。 – EkoostikMartin

+0

@EkoostikMartin:我已經更新了答案。 – Slauma

+0

謝謝,這有效,也讓我更好地理解一些EF概念。看起來EF有一些無關緊要的問題,這些問題使得與斷開連接的實體很難合作。我擔心隨着我的數據模型和操作要求變得更加複雜,情況會變得更糟。 – EkoostikMartin