簡版: 當我做了「myDbContext.Add(Entity)」時,我添加了2個實體,我剛纔查詢,但也添加到dbContext一個子實體(與我查詢的第一個實體有關),似乎EF沒有跟蹤他們作爲存在,因爲試圖插入Parent和Child實體。爲什麼我的dbContext的Add方法會添加2個父實體和1個導致PK約束錯誤的子實體
我不能添加特定的代碼,因爲政策,但基本上我做這樣的事情:
using (var db = new MyEntitiesContext())
{
/*don't know why, but code was already like this,
has some method which returns list of
SomeEntity type even knowing will have only 1 object*/
List<SomeEntity> entities = new List<SomeEntity>
entities = SomeMethod.SearchEntities(id);
SomeEntity current = entities.FirstOrDefault();
SomeEntity newOne = new SomeEntity();
//Then notice I use some of the values (all of them are int/string/date)
//from the "current" object to populate the "newOne"
newOne.Id = (from p in db.SomeEntities select p.Id).Max() + 1;
newOne.SomeDateValue = current.SomeDateValue;
newOne.someStringValue = current.someStringValue;
.
. //add some other values which doesnt' seem relevant to the issue
.
db.SomeEntity(newOne);
db.SaveChanges();
}
出於某種原因SaveChanges方法將導致相關的子實體違反的PK約束的例外。
經過調試和做一些「手錶」,我注意到我的dbContext對象「db」實際上持有SomeEntity的2個實體,「newOne」和「當前」我可以注意到,因爲「Count」值db.SomeEntity.Local屬性。
出於某種原因(糟糕的設計/理解)這樣做時:
db.SomeEntity.Add(newOne)
「當前」的實例加入以及旁邊一個孩子實體「地位」,所以調用SaveChanges()嘗試重新插入一個現有的「狀態」實體(除現有的「當前」實體外),並且將該異常拋出到SaveChanges()方法中。
我似乎可以分離是導致衝突的對象,是「當前」實體解決這個問題,它的子實體「狀態」,從的DbContext對象,但
這是爲什麼發生?或者我該如何避免這種情況?
我唯一的看法是,將值從「current」分配給「newOne」時可能導致行爲的一些參考,注意到「status」子實體沒有從「current」分配給「newOne」,I試圖使用「status」實體的新實例進行分配,並將其保留爲空,但沒有一個解決了這個問題。
note:我試圖在不同的「使用」塊中查詢「當前」對象,但問題依然存在。
注2:代碼編譯和被執行以及直到SaveChanges方法,上述樣品是不實際的代碼,但縮短/虛構版本試圖代表具有該問題的實際代碼的相同部分,因此一些語法/其他錯誤可以在上面的代碼中可以發現,問題更涉及到我缺乏的實體框架是如何工作和知識/或進行添加/調用SaveChanges
最後更新 的SearchEntities方法使用時跟蹤實體一個不同的上下文,通過在不同的上下文中「緩存」實體我導致EF將它們標記爲新的 - 插入,我只是拿着那個代碼在同一個dbContext中使用它,在那裏我插入一個新的實體並解決問題,似乎這是一個非常普遍的問題,但由於每個開發人員都陷入陷阱,所以這是一個非常普遍的問題。
你確定你的「類似」代碼也編譯和*產生相同的問題*? –
@Damien_The_Unbeliever不,不幸的是,我剛剛創建的樣本確實按預期工作,實際上我在數據庫對象中看到2個「SomeEntity」,但子實體沒有被添加到數據庫對象,並且SaveChanges方法無誤地執行,所以這個問題不存在,但即使在分離子實體的「真實」問題中,「當前」導致其 – Allende
表上的PK衝突,我認爲上下文將保存2個值,因爲正在跟蹤的實體.. –