2010-12-19 69 views
1

alt text「將子行添加到父級的子集合」v.s. 「將子項添加到datacontext的子集合中」

我會比較兩個方案以添加Rsvp行。你在生產中更喜歡哪一個?


方法1:添加一個新的RSVP對象的datacontext的RSVP集合

Rsvp r = new Rsvp(); 
r.AttendeeName = "xport"; 

r.DinnerId = 1;//there will be an exception if it is set to a Dinnner object that does not exist. 

entities.Rsvps.AddObject(r); 

entities.SaveChanges(); 

如果我們嘗試設置DinnerId到Dinner對象不存在,我們會得到一個異常。這種行爲是一致和直接的。


方法2:添加一個新的RSVP對象到Dinner對象的回函屬性

Rsvp r = new Rsvp(); 
r.AttendeeName = "xport"; 

r.DinnerId = 10000;//this Dinner does not exist! 

Dinner d = entities.Dinners.First(x => x.DinnerId == 1); 

d.Rsvps.Add(r); 

entities.SaveChanges(); 

一個RSVP對象的外鍵屬性DinnerId可以設置爲任意數量。將此Rsvp對象添加到Dinner對象的Rsvps集合時,DinnerId將被默認重寫。上面的示例顯示DinnerId設置爲10000,它是不存在的Dinner對象的Id。這是不可避免的行爲嗎?

回答

2

定義方法2

爲什麼?因爲如果沒有晚餐Rsvp不能存在。在這種關係中,晚餐是父 - 如果我們要創建一個存儲庫中,我們將創建一個DinnerRepository(晚餐是「聚合根」在DDD而言)

在問候你的注意 - 是的,這是可以避免的行爲 - 你應該做的是不要在模型上公開外鍵。這是您創建/更新模型時可用的選項。

這樣,關係必須創建/通過實體修改:

Rsvp r = new Rsvp(); 
r.AttendeeName = "xport"; 
r.DinnerId = 10000; // this throws a compiler error. good! we do not want people tinkering with FK's. 
Dinner d = entities.Dinners.First(x => x.DinnerId == 1); 
d.Rsvps.Add(r); // this is the correct way to add a RSVP 
entities.SaveChanges(); 

換句話說 - 創建/修改RSVP是通過晚宴的唯一途徑 - 與FK屬性不能被修改。

這是有道理的。

+0

我認爲異常將在運行時拋出,而不是在編譯時拋出。對? – xport 2010-12-19 06:46:05

+1

否 - 如果您從模型中排除外鍵,則'Rsvp'將不會*具有名爲'DinnerID'的屬性 - 因此生成的類/您的POCO也不會。所以試圖訪問這個屬性會拋出一個C#編譯器錯誤,因爲該屬性不存在。這正是應該發生的事情。 – RPM1984 2010-12-19 07:16:17

+0

我應該手動排除外鍵嗎?或者它可以在EDM嚮導中完成?預先感謝。 – xport 2010-12-19 07:43:27