2010-08-26 52 views
12

是否可以使用EF 4.0映射下面的POCO類?EF 4.0 - 使用私有字段映射到只讀屬性

public class MyClass 
{ 
    private string _myData; 

    public MyClass() 
    { } 

    public MyClass(string myData) 
    { 
    _myData = myData; 
    } 

    public string MyData 
    { 
    get 
    { 
     return _myData; 
    } 
    } 
} 

在NHibernate的,我認爲這是可能的,當我使用的訪問屬性像映射:

<class name="MyClass" table="MyTable"> 
    <property name="MyData" access="field.camelcase-underscore" column="MyCol" type="string" length="50" /> 
</class> 

我不知道是否有某些訪問相當於EF 4.0嗎?目前,我能夠映射類只如果我添加受保護的setter到MyData的屬性:

public string MyData 
    { 
    get 
    { 
     return _myData; 
    } 
    protected set 
    { 
     _myData = value; 
    } 
    } 

它的工作原理,但對傳統的類就意味着更新不具備制定者的所有屬性。

編輯:

我已經更新了最後的代碼示例,因爲它也不會帶私人二傳手工作。安裝者必須至少受到保護。如果二傳手是私人或不存在以下異常被拋出:

System.InvalidOperationException: 映射和元數​​據信息可能 無法發現的EntityType 「MyNamespace.MyClass」。

+0

沒有什麼私人二傳手發生什麼呢? – 2010-08-29 16:18:32

+0

我在問題中添加了說明。 – 2010-08-29 16:44:53

+0

Dang,System.InvalidOperationException!我有點希望它只是不包括它,我可以使用私人領域,使東西不堅持:http://stackoverflow.com/questions/3595404/how-not-persist-property-ef4-code-first – 2010-08-29 17:10:44

回答

5

我打了這一點,我的結論是:

  • 我不能映射不具有制定者在所有傳統類型。
  • 我可以映射具有私人setter的類型,但我必須在EDMX中設置Setter可訪問性。僅僅在POCO類中可靠地定義setter是不夠的 - EDMX必須知道它。
+2

什麼代碼優先(沒有EDMX),這可能嗎? – Shimmy 2012-01-18 06:46:57

+0

@Shimmy,請看我的答案。 EDMX的子類POCO,所以它對它本身就是魔術。您需要手動進行代碼優先。 – 2012-04-04 16:52:40

+1

嘗試這種私人物業的方法:http://blog.cincura.net/232731-mapping-private-protected-properties-in-entity-framework-4-x-code-first/ – 2012-10-09 09:23:19

6

這是代碼首先POCO對象,助陣擺振和其他人想知道這一切工作與代碼優先

我認爲你可能只是無法理解實體框架是如何工作的。這也讓我花了一段時間來掌握。

實體框架的工作方式是用一個代理類對您的POCO對象進行子類化,該代理類用於對對象進行序列化和反序列化。這意味着如果你有一個私有的方法或屬性(或者它們一起缺失),那麼子類方法就沒有辦法設置屬性。您希望Entity框架使用的setter和屬性必須是protected或public。

如果您希望延遲加載複雜的屬性,則還必須使這些屬性變爲虛擬,以便Entity Framework也可以代理這些屬性。如果你想加載它們,你必須使用Include方法。

要完全回答您的問題,是的,您必須將setter屬性添加到您希望Entity Framework爲您設置的所有屬性。不,實體框架不提供一種方法讓您映射沒有setter的屬性。

NHibernate的工作方式有點不同,它覆蓋了所有的屬性,我相信它在它生成的子類中使用私有變量,設置私有變量,然後重寫的屬性返回私有變量。 A.K.A.,NHibernate不需要屬性本身的setter,而Entity Framework實際設置屬性。實體框架這樣做的好處是它返回您創建的實際POCO對象,而不是像NHibernate那樣的子類對象。唯一一次獲得子類的對象是當你使用延遲加載的複雜屬性,其中實體框架返回代理子類。當您實際檢索數據時,代理會再次將自己設置爲您的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; 
     } 
    } 
} 
相關問題