2011-12-01 50 views
0

假設我有一個實體Parent和一個實體Child,這樣Parent有一個虛擬的ICollection Children屬性。在db中,這是從Child表到Parent表的簡單外鍵。有沒有一種方法可以告訴參考4.1哪些命令應該加載實體上的屬性?

現在說我有一個名爲Text的標量字符串屬性。在Text屬性的set方法期間,我想要訪問Children集合屬性中的實例。

當EF 4.1從數據庫重新構造父實體時(例如由於調用了ToList()),它會調用Text屬性的set方法,並且在填充Children集合之前似乎總是這樣做。

在調用Text標量字符串屬性上的set之前,是否有辦法告訴EF調用Children的virutal集合屬性集?

+1

你的屬性setter(設置'Text'屬性和set子集合)的行爲取決於你調用它們的順序 - 'x.Text =「a」; x.Children = someChildren;'給出的結果不是'x.Children = someChildren; x.Text =「a」;'不管你是手動還是EF在對象實現過程中都這麼做。不知何故,我對這樣的財產製定者有着不好的感覺。我會考慮重寫這段代碼。我認爲你不能影響EF中實體實現的內部實現。 – Slauma

+0

感謝您的解釋。 – danludwig

回答

2

您應該按照@ Slauma的建議從評論中更改代碼,因爲這是持久屬性的錯誤行爲。即使以下說明起作用,它也會非常容易出錯,因爲您將始終必須以特定方式查詢數據。

根據加載實體的方式,您的問題可以分爲多個部分。

延遲加載:

如果加載Parent and Child`懶加載你無法實現反向加載。

// Now parent is loaded 
var parent = context.Parent.First(); 

// Even with lazy loading enabled and your setter accessing nav. property it 
// should not load child collection because lazy loading should be temporarily 
// turned off during entity materialization to avoid unexpected lazy loads 

(未經測試),你可以嘗試手動加載所有的孩子第一,並要求家長以後:

// Now all child for given parent are loaded 
var child = context.Child.Where(c => c.Parent.Id == ...).ToList(); 

// Now parent is loaded and if you are lucky it configures navigation property 
// to loaded child prior to evaluating your setter - I guess setter will be 
// evaluated prior to fixing navigation properties so it will not work 
var parent = child[0].Parent; 

明確裝載將遭受同樣的問題。

預先加載:

的問題是一樣的,它是基於這樣how Include works

因此,如果您將孩子包含在父項中,父項將首先實現。

var parent = context.Parent.Include("Child").First(); 

在這種情況下,反向操作很可能於事無補,因爲調用

var childs = context.Child.Include("Parent").Where(...).ToList(); 

將評估記錄逐一每條記錄將包含一個小孩和父母,所以我覺得你第一次訪問父母你將只有一個孩子,並且你將依賴EF的操作順序(與延遲加載相同的問題)。

+0

感謝您的解釋。我會改變。 – danludwig

相關問題