【一个实体对象不能由多个 IEntityChangeTracker 实例引用】原因及解决方法
轉自firechun
使用ADO實體框架(EF)對建立了關系的表新增記錄時出現“一個實體對象不能由多個 IEntityChangeTracker 實例引用”錯誤,網上反復搜索后,沒有找到解決辦法,微軟的文檔也說的含糊不清,實際上,“IEntityChangeTracker ”到底是什么,我到現在也還是模模糊糊的。
問題現象:
一個角色表,一個用戶表,用戶表中的RoleId引用角色表中的RoleId。對用戶表添加記錄時,出現上述問題。
為了便于以后的維護和升級,我仍然對項目進行了分層,有了實體框架,數據訪問層和實體模型層自然可以用實體框架模型取代。業務層則仍按照傳統方式對每一個表都創建了相應的類。這里我就創建了分別處理角色和用戶的業務層:RoleManager和UserManager。
(題外話:MVC比傳統的三層結構更好用,不過這個項目比較緊,MVC我還沒有完全搞清楚,有些關鍵問題解決不了,所以這個項目還是決定用三層結構)
添加用戶數據的代碼如下:
表示層:
dmUser user=new User{UserId="test",UserName="test"};?????? //dmUser是表dmUser在實體模型中的映射
user.dmRoleReference.Value=RoleManager.GetRoleById(roleId);? //添加User表的關聯對象
UserManager.Add(user);? //調用UserManager中的Add方法向數據庫添加記錄
UserManager.Add方法中的主要代碼:
using(Entities db=new Entitles)??? //Entities,數據庫的實體模型
{
???? db.AddToUser(user);????? //這里出現本文所說的錯誤
???? db.SaveChanges();
}
百思不得其解,反復上網搜索,沒有找到答案,雖然找到一篇博文說解決了這個問題,但其所用的方法實在不敢恭維,應該會對程序造成很大的負面影響,而且他那個方法也不能適用到我的代碼中。
“對象服務使用?IEntityChangeTracker?的實例來跟蹤對附加到 ObjectContext 的對象的更改。對于每個被跟蹤對象,都有一個 IEntityChangeTracker 實例。”微軟的某一篇文檔中有這樣一句話,給了我一點提示。
經過多次編寫代碼驗證,終于明白,使用EF更新數據時,如果要更新的對象有相關的對象(換句話說,就是要更新的表有主外鍵關系),這些對象必須來自同一個IEntityChangeTracker 。
而我的問題就出在user.dmRoleReference.Value=RoleManager.GetRoleById(roleId);? 這里,在RoleManager.GetRoleById(roleId)方法中的實體對象和UserManager.Add方法中使用的實體對象不是同一個對象,也就產生了不同的IEntityChangeTracker 實例,因此出現本文所說的錯誤。
對UserManager.Add方法做如下修改即可
using(Entities db=new Entitles)??? //Entities,數據庫的實體模型
{
???? user.dmRoleReference.Value=db.dmRole.First(r=>r.RoleId==roleId);
???? db.AddToUser(user);??????
??? ?db.SaveChanges();
}
雖然這樣一來,roleId需要做為參數從表示層傳遞到Add方法中,但總比某位臺灣同行說處理這種問題用SQL語句要好吧(在google搜索時找這位同行的博客,他也遇到這個問題,他的解決方法就是直接使用SQL語句……),EF還是很強大滴,能省很多事……
轉載于:https://www.cnblogs.com/archor/archive/2011/10/31/3199374.html
總結
以上是生活随笔為你收集整理的【一个实体对象不能由多个 IEntityChangeTracker 实例引用】原因及解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stl_vector.h
- 下一篇: centos 5.x 安装 zendOp