我試圖創建具有特定角色的新用戶對象。 「角色」是EF中的一個現有實體。我用google搜索了一下,然後用stackoverflow,直到我臉色發青,我嘗試了所有似乎都適用於其他人的東西。但是當我嘗試保存新的用戶對象時,它首先嚐試創建一個新的「角色」,而不是僅僅通過引用現有角色來創建新的用戶對象。實體框架創建與現有實體關係的新實體,導致嘗試創建現有實體的新副本
我在做什麼錯?
Role myRole = new Role { ID = myUser.Role.ID };
myObjectContext.Roles.Attach(myRole);
myUser.Role = myRole;
if (myUser.ID == 0)
{
myObjectContext.Users.AddObject(myUser);
}
else
{
if (myUser.EntityState == System.Data.EntityState.Detached)
{
myObjectContext.Users.Attach(myUser);
}
myObjectContext.ObjectStateManager.ChangeObjectState(myUser, System.Data.EntityState.Modified);
}
myObjectContext.SaveChanges(SaveOptions.None);
編輯 - 經過測試...
好吧..所以我無論如何發現的 「事業」 的一些部分。我仍然不知道爲什麼這樣做,需要幫助。
基本上,我有兩組數據附加到我的新用戶對象。一個是「角色」,它是角色表中包含角色的FK。這顯示爲用戶的導航屬性,如「User.Role」。
第二組數據是稱爲「FIPS」的對象的集合,這是用戶與稱爲FIPS的另一個表之間的多對多關係。它們之間有一個關係表,它只包含兩列,分別是用戶和FIPS的外鍵。用戶的FIPS也是一個像「User.FIPS」一樣被引用的導航屬性。
以下是顯示在保存上下文之前向用戶對象分配FIPS和角色的整個代碼。
List<string> fipsList = new List<string>();
foreach (FIPS fips in myUser.FIPS)
{
fipsList.Add(fips.FIPS_Code);
}
myUser.FIPS.Clear();
foreach (string fipsCode in fipsList)
{
FIPS myFIPS = new FIPS { FIPS_Code = fipsCode };
myObjectContext.FIPSCodes.Attach(myFIPS);
myUser.FIPS.Add(myFIPS);
}
Role myRole = new Role { ID = myUser.Role.ID };
myObjectContext.Roles.Attach(myRole);
myUser.Role = myRole;
if (myUser.ID == 0)
{
myObjectContext.Users.AddObject(myUser);
}
else
{
if (myUser.EntityState == System.Data.EntityState.Detached)
{
myObjectContext.Users.Attach(myUser);
}
myObjectContext.ObjectStateManager.ChangeObjectState(myUser, System.Data.EntityState.Modified);
}
myObjectContext.SaveChanges(SaveOptions.None);
設置我的手錶,以檢查「myObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added)」中看到的狀態。當事情被添加到這一點。
只要將第一個相關對象添加到用戶對象,第二個尚未附加到上下文的相關對象就會添加到EntityState爲「已添加」的上下文中。
....會看看是否有辦法避免將相關實體附加到用戶實體,直到它們全部被連接到上下文之後。
--FOLLOWUP-- 行..好,我改變了代碼的順序,使相關的實體都被分配給用戶的實體之前附加到上下文..但只要第一相關實體被分配,第二個相關實體在ObjectStateEntries中顯示爲「添加」。 因此,我將其更改爲以下順序:
- 將所有相關實體附加到上下文。
- 刪除用戶對象上的現有關係到相關實體 類型。
- 將相關實體分配給用戶實體。
- 保存用戶實體。
而..現在..它的工作.. omg它的作品...!=)
我正試圖解決這個問題。由於我在VS 2010 IDE中沒有「myObjectContext.ChangeTracker」選項,因此此代碼適用於不同版本的EF。 – 2012-01-06 15:57:05
@AmandaMyer,它用於EF 4.2。如果你使用EF 4,你可以試試ObjectStateManager類。 – 2012-01-06 16:48:59
這不是正確的答案,但它讓我開始解決問題,所以我接受了這個答案。 – 2012-01-06 19:03:17