告诉EF 6忽略私有财产

时间:2014-02-17 20:57:38

标签: c# entity-framework

我正在使用Entity Framework 6.0.2将一些简单的手工编码模型映射到现有的数据库结构。目前的主要模式是:

public class Occurrence
{
    public int ID { get; set; }
    public Guid LegacyID { get; set; }
    public string Note { get; set; }
    public virtual ICollection<OccurrenceHistory> History { get; set; }
}

OccurrenceHistory模型与此无关,但该部分工作正常,因此EF会加载此模型的子记录。)

映射很简单,我尝试尽可能明确(因为随着应用程序的增长,会有一些不太直观的映射):

public class OccurrenceMap : EntityTypeConfiguration<Occurrence>
{
    public OccurrenceMap()
    {
        ToTable("Occurrence");
        HasKey(o => o.ID);
        Property(o => o.ID).IsRequired().HasColumnName("ID");
        Property(o => o.LegacyID).IsRequired().HasColumnName("LegacyID");
        Property(o => o.Note).IsUnicode().IsOptional().HasColumnName("Note");
    }
}

但是如果我向模型添加私有属性,EF会尝试将其映射到数据库。像这样:

private OccurrenceHistory CurrentHistory { get; set; }

(模型内部我会有一些维护该字段的逻辑,用于其他私有操作。)当EF生成SELECT语句时,它最终会查找名为CurrentHistory_ID的列,当然不存在。

我可以将属性设置为public并将映射设置为忽略它:

Ignore(o => o.CurrentHistory);

但我不希望该财产公开。该模型将在内部跟踪应用程序代码不应看到的一些信息。

有没有办法告诉EF忽略任何和所有私人成员?即使它是基于每个地图?我特别喜欢这样做,而不必向模型本身添加EF数据注释,因为这不仅仅是一个漏洞抽象(持久性无知的模型会有持久性信息)但它也意味着持有模型的域核心程序集在任何地方都会引用EntityFramework.dll,这是不理想的。

1 个答案:

答案 0 :(得分:3)

一位同事向我指出a blog post导致了一种非常实用的方法。

所以我拥有的是私有财产:

private OccurrenceHistory CurrentHistory { get; set; }

问题的核心是我无法在我的映射中使用它:

Ignore(o => o.CurrentHistory);

因为很明显,该属性是私有的,在此上下文中无法访问。博客文章建议公开一个引用私有财产的公共静态表达式:

private OccurrenceHistory CurrentHistory { get; set; }
public static readonly Expression<Func<Occurrence, OccurrenceHistory>> CurrentHistoryExpression = o => o.CurrentHistory;

然后我可以在映射中引用

Ignore(Occurrence.CurrentHistoryExpression);

与任何事情一样,它是利弊的混合体。但在这种情况下,我认为优点远远超过缺点。

优点:

  • 域核心程序集不需要引用EntityFramework.dll
  • 持久性映射完全封装在DAL程序集中。

缺点:

  • 模型需要公开一些关于其内部工作的信息。

con打破封装,但只是轻微。使用代码仍然无法访问该属性或其在实例上的值,它只能静态地看到属性存在。这真的不是什么大问题,因为无论如何开发人员都可以看到它。我觉得封装的精神仍然保留在模型的任何给定实例上。