【问题标题】:EF 6 database first make all properties virtual in generated entity classesEF 6 数据库首先使生成的实体类中的所有属性虚拟化
【发布时间】:2015-08-15 00:28:55
【问题描述】:

我有一个 db first edmx 模型。它生成的部分类具有非虚拟的简单属性。例如

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

    public partial class Entity
    {
     public int Id {get;set;} //not virtual
     public string SomeOtherProperty {get;set;} //also not virtual
     public virtual ICollection<RelatedEntity> RelatedCollection {get;set;} //but 'navigational' properties are virtual.
    }

如何告诉设计师让所有属性都虚拟化?

【问题讨论】:

  • 可能,无论如何。导航属性被声明为虚拟以提供数据的延迟加载。原始属性始终在加载,因此它们始终是非虚拟的。
  • 哦,太好了,我看到微软实际上并没有努力让测试变得简单。添加这个功能有多难?哦.. 亚历克斯..
  • 我看到你不应该添加这个功能。 EF 测试是一种集成测试,而不是一个单元,因此您不需要模拟对象。
  • 除非你正在做DDD 并且想要断言在你的实体上调用了方法,在这种情况下你希望你的模拟存储库返回一个模拟实体。然后你不能为你的实体的属性提供值。
  • 据我了解,实体不是域对象,它们是没有任何逻辑的数据传输对象。您不能使它们的属性虚拟只读复杂计算。 EF 应该从原始实体构建您的域对象。

标签: c# entity-framework properties virtual


【解决方案1】:

一个简单的解决方案。

在文件里面,找到CodeStringGenerator类,查找这个方法:

public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        Accessibility.ForProperty(edmProperty),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

一个简单的编辑就足够了:

public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        //make properties virtual.
        AccessibilityAndVirtual(Accessibility.ForProperty(edmProperty)),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

就是这样,供后人参考。

【讨论】:

  • 干净优雅。将所有属性修改为虚拟属性是否有任何已知的缺点?
  • 取决于应用于类的继承设计/策略。在这里应用的一个非常松散。如果一个人想要小心地设计继承树,以便只有所需的属性是可覆盖的,那么他们显然不应该使用它。无论如何,这是一种著名的常用模式,例如在 NHibernate 中,它允许代理挂接。性能影响很小:stackoverflow.com/a/530822/1144090,但这不应该在 2017 年 imo 中引起关注。
  • 将其定位到某些类型和属性的快速条件:if(edmProperty.DeclaringType.ToString() == "MyNamespace.MyModelName" &amp;&amp; new string[]{ "MyPropertyName1", "MyPropertyName2" }.Contains(_code.Escape(edmProperty)))
猜你喜欢
  • 2020-04-12
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 2019-09-15
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
相关资源
最近更新 更多