【问题标题】:EF 4.0 - mapping to readonly property with private fieldEF 4.0 - 映射到具有私有字段的只读属性
【发布时间】:2011-04-04 05:05:06
【问题描述】:

是否可以使用 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'。

【问题讨论】:

  • 没有私人二传手会怎样?
  • 我在问题中添加了描述。
  • 当,System.InvalidOperationException!我有点希望它只是不包括它,我可以使用私有字段来使某些东西不持久:stackoverflow.com/questions/3595404/…

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


【解决方案1】:

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

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

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

如果您希望延迟加载复杂的属性,您还必须将这些属性设为虚拟,以便 Entity Framework 也可以代理这些属性。如果你想预先加载它们,你必须使用 Include 方法。

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

NHibernate 的工作方式有点不同,它覆盖了你的所有属性,我相信它在它生成的子类中使用私有变量,设置私有变量,然后被覆盖的属性返回私有变量。 A.K.A.,NHibernate 不需要属性本身的设置器,而实体框架实际上设置了属性。 Entity Framework 这样做的好处是它返回您创建的实际 POCO 对象,而不是像 NHibernate 这样的子类对象。获得子类对象的唯一时间是使用延迟加载的复杂属性时,其中 Entity Framework 返回代理子类。当您实际检索数据时,代理会再次将自己设置为您的 POCO 类。

您的 setter 应该是公开的或受保护的,就像您在问题中所说的那样:

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;
        }
    }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • @Shimmy,请看我的回答。 EDMX 是 POCO 的子类,因此它本身就具有魔力。您需要手动执行代码优先。
    • 对私有财产尝试这种方法:blog.cincura.net/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 2021-04-18
    • 2017-06-23
    • 2019-04-08
    • 1970-01-01
    • 2012-09-25
    相关资源
    最近更新 更多