拥有所有实体派生自的 BaseEntity 类型或接口会更好吗?
Posted
技术标签:
【中文标题】拥有所有实体派生自的 BaseEntity 类型或接口会更好吗?【英文标题】:Is it better to have a BaseEntity type or Interface that all entities derive from? 【发布时间】:2011-07-11 20:20:54 【问题描述】:目前我创建了一个基础实体类型,我的所有实体都将从该类型派生。
public abstract class BaseEntity
/// <summary>
/// Key Field for all entities
/// </summary>
///
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id get; set;
/// <summary>
/// Date entity was created
/// </summary>
public DateTime DateCreated get; set;
/// <summary>
/// Last date Modified
/// </summary>
public DateTime DateModified get; set;
/// <summary>
/// keep track of Row Version used for concurrency
/// </summary>
[Timestamp]
public Byte[] RowVersion get; set;
我正在考虑将我的模型与实体框架解耦,以便它不依赖它。我想要另一个用于我的 EF 实施的项目。因此,我想在该项目中包含映射,这些映射将构成我的模型中的关系。
因为我的 BaseEntity 类是一个抽象类,所以我最好的方法是保留我的 [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 和 [TimeStamp] 属性,以便它适用于使用流式 API 的所有派生实体和单独的映射文件?我认为我不能设置建模器来添加 BaseEntity 映射,因为它是一个抽象类。我是否应该创建一个具有所有基本功能的界面并为所有实体重复映射?
我正在使用 EntityTypeConfiguration 类并为我的所有实体创建单独的映射类。
【问题讨论】:
我更喜欢接口。保持耦合更松散,并且不会因为基类未映射到架构而惹恼实体框架。 复制:***.com/q/15578528/861716 【参考方案1】:你可以使用基类:
public abstract class BaseEntity
public Guid Id get; set;
public DateTime DateCreated get; set;
public DateTime DateModified get; set;
public Byte[] RowVersion get; set;
现在取决于您是否要映射继承。我猜你不希望这样定义你的配置:
public class BaseEntityConfiguration<TEntity> : EntityTypeConfiguration<TEntity>
where TEntity : BaseEntity
public BaseEntityConfiguration()
HasKey(e => e.Id);
// This is not very good - check http://***.com/questions/6098972/guid-comb-strategy-in-ef4-1-codefirst/6100606#6100606
Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(e => RowVersion).IsRowVersion();
现在对于从BaseEntity
派生的每个实体,从BaseEntityConfiguration
派生其配置,
【讨论】:
@Ladislav:这个BaseEntityConfiguration<TEntity>
真的适用于BaseEntity
本身以外的任何类型吗?我刚刚与 DDiVita 进行了这个 (***.com/questions/7177508/…) 令人沮丧的讨论,他说“它有效”,而另一方面我确信它不是,因为我相信这是他问题中异常的根源: “属性 'Id' 不是类型上的声明属性...”。 (我在我的回答中做了这个小例子,希望它是一个证明。)但是在这里阅读你的回答我现在变得不确定了。
@Slauma:它有效,但它有效的唯一原因是BaseEntity
不是一个实体——它只是一个类。您不能创建DbSet<BaseEntity>
。这不是 TPC 继承,这是针对具有不是实体的共享父类的 POCO 实体。如果BaseEntity
也将是实体,那么您确实会收到该错误。
啊啊啊啊,现在我明白了!我什至不知道我可以有一个非实体基类。现在,这是一个很好的答案,+1,哈哈 :)
@Slauma:这是 POCO 有可能定义自定义基类的要点。【参考方案2】:
类继承基类不是一个好习惯。
对于这些情况,最好优先考虑组合并降低继承的优先级。
因此,您应该包含一个类作为每个实体的一个属性,该类表示具有 BaseEntity 类属性的元数据。
GL
Source
【讨论】:
你似乎不明白为什么这里需要一个基类或接口(没有别的)。 解决策略必须通过组合来解决,因为继承不是一个好的做法。而不是从基类继承的实体,它们应该与类成员组成基类。如有必要,我附上一个例子。 在 DDD 中,您(可以说)是对的。 OP 唯一要做的就是拥有带有 ID 和审计字段的数据库表。以上是关于拥有所有实体派生自的 BaseEntity 类型或接口会更好吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JPA 的 BaseEntity 中实现 equals() 和 hashcode() 方法?