2013-04-08 47 views
11

我碰到我的DbContext以下錯誤:「多重約束違反關係中的作用‘myEntity所’「。 MyModel.FK_ChildEntities_MyEntities'具有多重性1或0..1「。違反多重性約束。關係中的作用「......」「......」有多重1或0..1

使用ASP.NET,實體框架4

與分離實體

錯誤發生的工作,第二次我嘗試重新連接的實體到的DbContext。該場景是一個不成功的保存,然後重新嘗試。

我在會議上分離實體。用戶更改表單中的屬性,添加內容,刪除內容並最終點擊保存。我得到的實體從的DbContext的新實例附加的副本,申請從分離的實體變爲連接實體,驗證,發現有錯誤並中止。用戶更改任何內容並再次保存。

在第二保存,整個保存過程重複,只是這一次它都去地獄。幾乎所有的東西都是重複的,導致一個或者所有的錯誤。來自視圖和查找表的值只能是引用,並且會創建新的和重新分配的ID。大部分我已經能夠解決的問題,但我留下了多重性錯誤。子元素正在被創建爲其他子元素的精確副本,只有在已添加狀態下才會被創建爲唯一的ID。或者,如果我參考某些屬性,而不是克隆未修改的孩子,則會刪除新的屬性。無論哪種方式,沒有任何代碼正在執行,因爲它是第一次。

我丟棄的DbContext和連接的實體每次保存嘗試的實例。我認爲這足以回覆任何變化,但必須堅持到底。唯一沒有被discared或重置的東西是分離的實體,它在會話中,但我沒有做任何修改。至少不是直接的。

代碼(非常簡化的)是這樣的:

void Save() 
{ 
using (var context = new MyContext()) 
{ 
    // detached entity from session 
    MyEntity detachedEntity = (MyEntity)Session["DetachedEntity"]; 

    // attached entity from context 
    MyEntity attachedEntity = context.MyEntities.Single(x=>x.id == detachedEntity.id);  


    // <remove children representing lookup table elements from detachedEntity to prevent duplicates> 
    // <remove children representing view elements from detachedEntity to prevent duplicates> 


    // <apply changes from detachedEntity to attachedEntity> 


    // <add new children> 
    // <remove deleted children> 
    // <update modified children> 


    // <set entity state to unchanged on view and lookup elements of attachedEntity to ensure no duplicates...> 


    // <validate> 


    if (errors.count>0) 
    // <report errors> 
    else 
    context.SaveChanges(); 
} 
} 

作爲一個例子,這會產生多個錯誤:

// represents first save: 
    using (var context = new MyContext()) 
    { 
     // detached entity from session 
     MyEntity detachedEntity = (MyEntity)Session["DetachedEntity"]; 

     // attached entity from context 
     MyEntity attachedEntity = context.MyEntities.Single(x=>x.id == detachedEntity.id);  

     int debug1 = context.ChangeTracker.Entries<ChildEntity>().Count(); // debug1 == 0; 

     attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First()); 

     int debug2 = context.ChangeTracker.Entries<ChildEntity>().Count(); // debug2 == 1; 

    } 

// represents second save: 
    using (var context = new MyContext()) 
    { 
     // detached entity from session 
     MyEntity detachedEntity = (MyEntity)Session["DetachedEntity"]; 

     // attached entity from context 
     MyEntity attachedEntity = context.MyEntities.Single(x=>x.id == detachedEntity.id);  

     int debug1 = context.ChangeTracker.Entries<ChildEntity>().Count(); // debug1 == 0; 

     attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First()); 

     int debug2 = context.ChangeTracker.Entries<ChildEntity>().Count(); // multiplicity error; 

    } 

回答

14

不知何故的DbContext記住加入到它什麼對象。如果完全相同的對象顯示出來兩次,它...吹

,而不是從我脫離實體添加子實體連接的一個,我應該已經創建每個孩子

ChildEntity detachedChild = detachedEntity.ChildEntities.First(); 
attachedEntity.ChildEntities.Add(new ChildEntity { 
    propertyA = detachedChild.propertyA, 
    propertyB = detachedChild.propertyB 
}); 

的新副本而不是

attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First()); 
+0

所以它會創建一個新的'ChildEntity'並將它添加到'ChildEntity Table',然後建立關係 – Mohsen 2013-08-25 06:54:11

+0

這發生在我身上時,我的'attachedEntity'('MyEntity')有一個'ChildEntity'集合,但是我的' ChildEntity'模型沒有收集「MyEntity」。但我只想保留'ChildEntity'的一個實例,所以當我將'MyEntity'集合添加到'ChildEntity'時,我可以使用'attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First());' – Reuben 2015-06-17 23:50:33

+0

@Reuben:最後一行的問題是,如果啓用延遲加載,它將加載該實體的所有ChildEntities。絕對不是很有效率。 – 2015-10-02 22:35:16

5

問題是應該爲detachedChild.parent指定attachedParent。

foreach(var detachedEntity in detachedEntities) 
{ 
    attachedEntity.ChildEntities.Add(detachedEntity); 
    detachedEntity.ParentEntity = attachedEntity; 
} 
+1

這個。你會認爲把一個孩子附加到一個新的父母身上可以明顯看出真正的父母是誰,但沒有。謝謝,這是解決方案。 – 2018-02-21 04:20:24

1

請確保檢查您嘗試添加的對象的屬性。在我的情況下,它被錯誤引用的每個它不喜歡,因此你扔在這裏了同樣的錯誤添加相同無效的對象。

0

EF 6更新

對我來說,對象狀態的設置,在加入工作聽起來合乎邏輯,也

ChildEntity detachedChild = detachedEntity.ChildEntities.First(); 
var newChild = new ChildEntity { 
    propertyA = detachedChild.propertyA, 
    propertyB = detachedChild.propertyB 
}); 

// Mark all added entity entity state to Added 
attachedEntity.ChildEntities.Add(newChild); 
         db.Entry(newChild).State = EntityState.Added; 

http://www.entityframeworktutorial.net/EntityFramework4.3/update-one-to-many-entity-using-dbcontext.aspx

0

我經歷過這樣的錯誤時,我有過導航性能未被設置或屬於錯誤的導航屬性Code First DBContext

相關問題