将表映射到DDD体系结构中的域类

时间:2013-06-09 21:32:23

标签: domain-driven-design

我的应用程序分为几个程序集。

MyProject.Core程序集包含所有Domain对象,如Person和Sale以及接口存储库,如IPersonRepository和ISaleRepository。

MyProject.Data应该处理持久性,但我对它应该如何工作有点困惑。我应该使用Entity Framework将我的表映射到域模型吗?我应该使用Fluent API吗?或者我应该实例化模型类并手动填充它们?

3 个答案:

答案 0 :(得分:4)

IMO您不应该尝试将域模型对象用作实体框架实体。您将无法正确制作由原子方法组成的封装域对象。相反,他们需要具有EF所需的getter和setter的公共属性,这导致Anemic Domain Model

基本上:如果您尝试将域对象加倍为实体框架实体,则会损害设计。

相反,我使用memento pattern,我使用作为纪念品的EF实体重新保存我的域对象。

鉴于EF只能使用普通的POCO,我会将这些类放在托管DbContext / Respositories的程序集的不同程序集中,因为您的模型需要引用它们。因为它们只是POCO,所以你不会将你的模型与EF绑在一起。

所以你可能有三个组件:

  • MyProject.Model ...其中包含您的DDD模型类
  • MyProject.Data ...包含DBContext和存储库
  • MyProject.Mementos ...其中包含您的EF POCO

示例:

public class PersonRepository  : EntityFrameworkRepository, IPersonRepository
{
      public Person GetById(Guid personId)
      {
           using (MyDbContext ctx = new MyDbContext())
           { 
               var personMemento = (from p in ctx.People
                                   where p.PersonId == personId
                                   select p).FirstOrDefault(); 


               return Person.RestoreFromMemento(personMemento);

           }
      }
}

答案 1 :(得分:1)

  

MyProject.Data应该处理持久性,但我对它应该如何工作有点困惑。我应该使用Entity Framework将我的表映射到域模型吗?我应该使用Fluent API吗?或者我应该实例化模型类并手动填充它们?

使用您所知道的,或者如果允许,使用您想要学习的内容。

无论哪种方式,您都不应将任何特定于数据库的信息泄漏回域模型或对模型施加任何数据库限制。

答案 2 :(得分:0)

行业标准做法是使用某种对象/关系映射器(如Entity Framework或NHibernate等)来加载和持久化您的实体。

O / RM是用于弥合面向对象的 laguages与关系数据库之间的阻抗不匹配的工具。

它们通常与存储库模式结合使用。

使用这些工具并不是必需的,您可以手动将实体保存到数据库,或者可能构建自己的O / RM,但是会产生许多不必要的麻烦。通过使用O / RM工具,您将获得许多其他构建DDD应用程序的经验。

值得注意的是,O / RM不仅适用于DDD应用程序。

在我的应用程序中,数据层通常是一些存储库,NHibernate映射文件和任何其他NHibernate实现代码。