DDD聚合和实体框架。哪种方式更可取?

时间:2016-02-07 16:54:16

标签: c# entity-framework orm domain-driven-design

我对这个问题有点困惑。我有一个在数据库中表示的实体Product。它看起来像POCO。这是一个示例(为简单起见,我使用属性而不是流畅的api。)

public class Product
{
    [Key]
    public int Id { get; set; }   
    //other properties that have mapping to db
}

但现在我想避免AnemicDomainModel anti-pattern

所以我将使用方法和属性填充Product模型,这些方法和属性没有映射到db,所以我应该使用[Ignore]

public class Product
{
    [Key]
    public int Id { get; set; }   
    [Ignore]
    public object FooProperty { get; set; } 
    //other properties that have mapping to db
    //other properties and methods that do not have mapping to db
}

我认为这种方式破坏了我的模型。在this article我找到了可接受的解决方法。它的想法是将Product(域模型)和ProductState(存储在数据库中的产品状态)分开。所以ProductProductState的包装。

我真的想知道其他开发者的观点。非常感谢您的回答。

我明白我的真实问题听起来像是:“我应该将数据模型和域模型分开吗?我可以将EF实体从贫血变为富?”

2 个答案:

答案 0 :(得分:4)

为了确保对实体的持久性无知,我发现EF Fluent Mapping要好于数据注释。映射在外部文件中声明,因此,如果持久层中的某些内容发生更改,通常您的实体不必更改。但是,EF仍有some things you can't map

您链接的Vaughn“支持状态对象”解决方案很不错,但它是一个额外的间接层,为您的应用程序增加了相当大的复杂性。这是个人品味的问题,但我只会在您绝对需要实体中由于EF缺点无法直接映射的情况时使用它。它也适用于事件采购方法。

答案 1 :(得分:1)

实体框架的优点在于它允许您使用可以使用Fluent API定义的映射将数据库表映射到域模型,因此不需要具有单独的数据实体。这与其前身Linq To SQL相比,您可以将每个表映射到单个数据实体。

采用以下示例,对于学生和课程的范例 - 学生可以参加许多课程,课程可以有很多学生,因此数据库设计中存在多对多的关系。这将包括三个表:学生,课程,StudentToCourse。

EF将允许您使用Fluent API映射在关系的任一侧创建许多集合,而无需在模型中定义中间表(StudentToCourse)(StudentToCourse在DOMAIN模型中不存在),您只会你的领域需要两门课程,即学生和课程。而在LinqToSQL中,您必须将模型中的所有三个定义为数据实体,然后在数据实体和域模型之间创建映射,从而导致大量管道工作开放给bug。

贫血与富域模型的论点应该对您的模型和数据库表之间的映射几乎没有影响,但是要关注您放置行为的位置 - 在域模型或服务层中。