EF 4.0 - 映射到具有私有欄位的只讀屬性
是否可以使用 EF 4.0 映射以下 POCO 類?
public class MyClass { private string _myData; public MyClass() { } public MyClass(string myData) { _myData = myData; } public string MyData { get { return _myData; } } }在 NHibernate 中,我認為在映射中使用 Access 屬性是可能的,例如:
<class name="MyClass" table="MyTable"> <property name="MyData" access="field.camelcase-underscore" column="MyCol" type="string" length="50" /> </class>我想知道 EF 4.0 中是否有一些 Access 等價物?目前,只有在將受保護的 setter 添加到 MyData 屬性時,我才能映射該類:
public string MyData { get { return _myData; } protected set { _myData = value; } }它可以工作,但對於遺留類,這意味著更新所有沒有設置器的屬性。
編輯:
我更新了最後一個程式碼範例,因為它也不適用於私有設置器。Setter 必須至少受到保護。如果 setter 是私有的或不存在,則拋出以下異常:
System.InvalidOperationException:找不到實體類型“MyNamespace.MyClass”的映射和元數據資訊。
我玩了一點點,我的結論是:
- 我無法映射根本沒有 setter 的遺留類型。
- 我可以映射具有私有 setter 的類型,但我也必須在 EDMX 中設置 Setter 可訪問性。在 POCO 類中定義 setter 是不夠的 - EDMX 必須知道它。
這是針對 Code First POCO 對象的,以幫助 Shimmy 和其他想知道這一切如何與 Code First 一起工作的人
我認為您可能只是不了解實體框架的工作原理。這也花了我一段時間來掌握。
實體框架通過使用代理類對您的 POCO 對象進行子類化來工作,該代理類用於序列化和反序列化您的對象。這意味著如果您有一個私有的 set 方法或屬性(或者它一起失去),則子類方法無法設置該屬性。您希望實體框架使用的設置器和屬性必須是受保護的或公共的。
如果您希望延遲載入複雜的屬性,您還必須將這些屬性設為虛擬,以便 Entity Framework 也可以代理這些屬性。如果你想預先載入它們,你必須使用 Include 方法。
要完全回答您的問題,是的,您必須將 setter 屬性添加到您希望 Entity Framework 為您設置的所有屬性中。不,Entity Framework 沒有為您提供映射沒有設置器的屬性的方法。
NHibernate 的工作方式有點不同,它覆蓋了你所有的屬性,我相信它在它生成的子類中使用私有變數,設置私有變數,然後被覆蓋的屬性返回私有變數。AKA,NHibernate 不需要屬性本身的設置器,而實體框架實際上設置了屬性。Entity Framework 這樣做的好處是它返回您創建的實際 POCO 對象,而不是像 NHibernate 這樣的子類對象。您獲得子類對象的唯一時間是使用延遲載入的複雜屬性時,Entity Framework 返回代理子類。當您實際檢索數據時,代理再次將自己設置為您的 POCO 類。
您的二傳手應該是公開的或受保護的,就像您在問題中所說的那樣:
public class MyClass { private string _myData; public MyClass() { } public MyClass(string myData) { // In case there is specialized logic, you should call the property setter here // unless the property is a virtual property. You should never call any virtual // methods or properties in your constructor. MyData = myData; } public string MyData { get { return _myData; } protected set { _myData = value; } } }