Entity Framework想說愛你不容易,這麼多的報錯,這麼多的限制,該如何解決?

weixin_34115824發表於2017-11-15

首先看一下采用MODEL FIRST的方式設計的實體模型物件關係圖:

注意:EntityOne中有導航屬性:EntityTwo

在如下程式碼中的幾種情況進行新增操作,均會報錯,新增都不會成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
static void Main(string[] args)
       {
           Model1Container context = new Model1Container();
 
           //第一種情況:EntityOne有導航屬性EntityTwo ,新增時必需同時指定新增的EntityTwo ,否則報錯:“Model1Container.EntityOnes”中的實體參與“EntityOneEntityTwo”關係。找到 0 個相關的“EntityTwo”。應有 1 個“EntityTwo”。
           var objSetOne = context.EntityOnes;
           //objSetOne.MergeOption = MergeOption.NoTracking;
           objSetOne.AddObject(new EntityOne() { ID = 2, P1 = "pp1", P2 = "pp2", P3 = "pp3"});
           context.SaveChanges();
 
            
          //第二種情況:有些時候,我們的EntityTwo可能需要先建立,但這樣執行同樣報錯:“Model1Container.EntityTwos”中的實體參與“EntityOneEntityTwo”關係。找到 0 個相關的“EntityOne”。應有 1 個“EntityOne”。
           var objSetTwo = context.EntityTwos;
           //objSetTwo.MergeOption = MergeOption.NoTracking;
           objSetTwo.AddObject(new EntityTwo() { ID = 2, T1 = "tt1", T2 = "tt2", T3 = "tt3" });
           context.SaveChanges();
 
          //第三種情況:有些時候,我們的EntityTwo可能已經在之前已經建立了,此處只是查詢出來,用來在需要新增EntityOne時賦值給關聯屬性:EntityTwo,但依舊報錯:“EntityOneEntityTwo”AssociationSet 中的關係處於“Deleted”狀態。如果有多重性約束,則相應的“EntityOne”也必須處於“Deleted”狀態。
          var objSetTwo = context.EntityTwos;
           var entityTwo = objSetTwo.Single(t=>t.ID==2);
 
           var objSetOne = context.EntityOnes;
           //objSetOne.MergeOption = MergeOption.NoTracking;
           objSetOne.AddObject(new EntityOne() { ID = 3, P1 = "pp1", P2 = "pp2", P3 = "pp3", EntityTwo = entityTwo });
           context.SaveChanges();
 
 
 
       }

只有一種情況才能正確執行新增,如下:

1
2
3
4
5
Model1Container context = new Model1Container();
 
            var objSetOne = context.EntityOnes;
            objSetOne.AddObject(new EntityOne() { ID = 2, P1 = "pp1", P2 = "pp2", P3 = "pp3", EntityTwo = new EntityTwo() {ID=2, T1 = "tt1", T2 = "tt2", T3 = "tt3" } });
            context.SaveChanges();

說明只有同時完成新增EntityOne與關聯屬性EntityTwo,才能成功,但現實是這樣的嗎?比如:一個人先後寫了幾本書,那肯定是先有人這個實體,然後才會有書這個實體,每寫一本書,書的作者關聯屬性應該是人這個實體,但按照上面的測試,新增一本書就必需新增一個人,這顯然是不對的,該如何解決呢?我目前沒有找到更好的解決辦法,唯一的辦法就是不要導航,但這又不符合物件導向原則,所以在此還請大家多多指教,謝謝!

 

解決方案分享:

通過網友評論指點,我將兩個實體的關聯關係,由原來的1:1改為1:0,這樣第一種與第三種方式是沒有問題的,第二種依然存在問題,因為第二種方式只建立被關聯的實體EntityTwo,而EntityTwo可有一個外來鍵欄位EntityOneEntityTwo_EntityTwo_ID,若沒有相應的EntityOne的ID,是無法建立成功的,也就是說第二種方式只有給定外來鍵的值,才有可能建立成功。算是都解決了。但仍存在一個問題,正如上面我舉的例子,人與書,人可以不知道會以後會寫書,也就是人不用關聯書,但書寫出來一定是有人的,也就是書的作者一定是關聯人的,人可以寫多本書,多本書的作者可以都是同一個人,然而上面採用MODEL FIRST生成的實體,是不能滿足人與書這種關係的,需要進行調整,調整如下圖示:

 

 

這樣設定好關係後,再用上面的三種方式來進行操作,都可以通過了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第一種:建立單個人物件
 //var objSetPerson = context.Persons;
 //objSetPerson.AddObject(Person.CreatePerson(1,"夢在旅途"));
 //context.SaveChanges();
 
 
 //第二種:建立書,並同時指定書的作者ID
 //var objSetBook = context.Books;
 //objSetBook.AddObject(Book.CreateBook(1,".NET學習1.0",1));
 //context.SaveChanges();
 
 
 //第三種:查詢到指定的人,並在建立書的同時指定人實體
 var objSetPerson = context.Persons;
 Person person = objSetPerson.Single(t => t.ID == 1);
 var objSetBook = context.Books;
 objSetBook.AddObject(new Book() { ID = 2, Name = ".NET學習2.0", AuthorInfo=person });
 context.SaveChanges();

  

本文轉自 夢在旅途 部落格園部落格,原文連結:  http://www.cnblogs.com/zuowj/p/4655254.html,如需轉載請自行聯絡原作者

相關文章