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