EF 4.0 - 使用私有字段映射到只读属性

时间:2010-08-26 10:46:17

标签: .net entity-framework mapping entity-framework-4

是否可以使用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。塞特必须至少受到保护。如果setter是私有的,或者在抛出异常后不存在:

  

System.InvalidOperationException:   映射和元数​​据信息可以   找不到EntityType   'MyNamespace.MyClass'。

2 个答案:

答案 0 :(得分:6)

这是针对Code First POCO对象,帮助Shimmy和其他人想知道这一切如何与Code First一起使用

我认为您可能不了解实体框架的工作原理。这花了我一段时间才掌握。

实体框架通过使用代理类对POCO对象进行子类化来实现,代理类用于序列化和反序列化对象。这意味着如果您有私有set方法或属性(或者它们一起丢失),则子类方法无法设置该属性。您希望实体框架使用的setter和属性必须是受保护的或公共的。

如果您希望懒惰地加载复杂属性,则还必须创建这些虚拟属性,因此Entity Framework也可以代理这些属性。如果您想要加载它们,则必须使用Include方法。

要完全回答您的问题,是的,您必须将setter属性添加到您希望Entity Framework为您设置的所有属性中。不,实体框架不提供映射没有设置器的属性的方法。

NHibernate的工作方式略有不同,因为它覆盖了所有属性,我相信它在它生成的子类中使用私有变量,设置私有变量,然后重写的属性返回私有变量。 A.K.A.,NHibernate不需要在属性本身上设置setter,而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;
        }
    }
}

答案 1 :(得分:5)

我玩了这一点,我的结论是:

  • 我无法映射完全没有setter的遗留类型。
  • 我可以映射具有私有设置器的类型,但我也必须在EDMX中设置Setter可访问性。在POCO类中定义setter accessibily是不够的 - EDMX必须知道它。