2015-12-31 180 views
0

我正在使用實體框架,我想更新導航屬性。例如,我有一個Profile對象,它的導航屬性爲Gender。我想改變Gender。我可以更新Profile對象的GenderID(這是外鍵),或者用Gender對象初始化Gender;所以:更新導航屬性或外鍵?

profile.GenderID = 2; 

Profile.Gender = new Gender{ID=2, Name = "Female"}; 

比方說,我有這樣的語言的集合,代表一個1:N的關係。我有一份LanguageIDs或語言列表嗎?如何更新列表而不會對數據庫造成影響?

如果我選擇後者,告訴實體框架提交更新或插入?它是主鍵嗎?

+0

你只需要更新你的配置文件中的外鍵字段;不需要再次實例化性別。 profile.GenderId = 2會做 – techspider

+0

謝謝!我在我的問題中加入了一個1:n關係,我有一個像語言這樣的列表。我沒有外鍵列表。有什麼方法可以在沒有命中的情況下更新列表? – Eitan

+0

*我有一個列表的語言ID和語言列表。如何更新列表而不會對數據庫造成影響?如果我選擇後者*這很混亂。你想更新什麼?什麼是*後者*? –

回答

1

您有以下選擇:

1.更新父對象的外鍵字段:

profile.GenderID = 2; 

這有更新後那場模型,然後的影響您在上下文上調用.SaveChanges();,數據庫將隨着對象上的導航屬性一起更新。


2.更新導航屬性直接到現有的對象已經附加到上下文:在這種情況下

var femaleEntity = context.Genders.First(g=>g.Name == "Female"); 
profile.Gender = femaleEntity; 

的導航屬性被更新:

例如但是.GenderId字段未在profile對象上更新,直到您致電context.SaveChanges();,然後EF會將新值寫入數據庫中的GenderId列,並更新profile對象上的.GenderId屬性。


3.更新使用新的對象導航屬性:

Profile.Gender = new Gender{ID=2, Name = "Female"}; 

這裏EF將嘗試添加一個新的性別一行到數據庫的2號和名稱=女。如果數據庫的Gender表中沒有'Female'行,並且如果Gender ID是由數據庫分配的標識,那麼您幾乎可以肯定只想這樣做。在調用.SaveChanges()時,它將被分配的值覆蓋。 )。


忽略EF更新對象的細節時,前2個選項大致相當*,但第3個選項具有不同的行爲。我們需要知道(或確定)我們是否需要鏈接到現有的Gender對象或將新對象添加到數據存儲區。

完全同樣的原則也適用於你的1:許多關係太:

profile.Languages = new List<Languages> 
{ 
    new Language{Name = "Spanish"} 
} 

會在語言表中的新行,而:

var spanish = context.Languages.First(l=>l.Name == "Spanish"); 
profile.Languages = new List<Languages> 
{ 
    spanish 
} 

發現現有的行名爲「西班牙'然後更新導航屬性。

如果您有存儲在一個變量語言ID的列表要更新與關聯的語言對象的導航屬性你可以這樣做:

var languagesToAdd = context.Languages.Where(l=>languageIds.Contains(l.ID)).ToList(); 
profile.Languages = languagesToAdd; 

*當然有與選項2的性能損失如果你不是已經在內存中有一個附加的Gender對象,例如通過調用.First()(如我的例子)來獲取數據,那麼當然會需要另一次來回數據庫。

+0

感謝您的回答!比方說,我想要做選項1:更新父對象....中的外鍵字段,但對於n:n關係?我有一個語言ID列表(不是語言對象),我想用我的語言ID列表來更新這個配置文件。以性別爲例,我有GenderID,但使用語言我沒有LanguageID。 – Eitan

+0

@Eitan我更新了答案 –

+0

當我調用context.Languages.Where(....,它查詢數據庫。我不能只更新ID沒有額外的命中數據庫? – Eitan