【问题标题】:Questions regarding Entity Framework + DDD关于实体框架 + DDD 的问题
【发布时间】:2009-10-06 20:36:20
【问题描述】:

我很难找到在 DDD 样式模式中使用 EF 的直接示例。这也是我第一次使用 DDD,对解决方案布局以及如何使用一些 DDD 模式有一些疑问。

1) 我见过的大多数关于使用带 EF 的存储库模式的示例只显示了专门的模型接口,例如 IContactRepository,然后是实现该接口的具体类型。理想情况下,我喜欢使用 IRepository 之类的东西,它具有 CRUD 操作的基本功能集。然后,如有必要,我可以创建专门的存储库,例如 IContactRepository : IRepository,因为我的大多数模型都不需要扩展。我在吠叫错误的树吗?有人可以提供这种实施方式的示例吗?

2) 现在我的解决方案分为以下三个项目:模型(包含我的 EDM)、存储库和服务。这是合适的还是我没有考虑但应该考虑的另一种布局方法?

3) 我已经看到了具有返回 IQueryable 的 Query(Func)/Query() 方法的存储库示例。是臭臭的还是有什么不好的地方?

【问题讨论】:

    标签: entity-framework domain-driven-design repository-pattern


    【解决方案1】:

    我想回答#3...

    我认为它不那么“臭”,而更“懒惰”。这是我在互联网上看到的典型“存储库”...

    public interface IRepository {
      // Query operations.
      IQueryable<T> All<T>();
      IQueryable<T> Find<T>(Expression<Func<T, bool>> expression);
      T Single<T>(Expression<Func<T, bool>> expression);
    
      // Save operations.
      T Add<T>(T objectToAdd);
      void Delete<T>(T objectToDelete);
      T Update<T>(T objectToUpdate);
    }
    

    据我所知,这与其说是一个存储库,不如说是一个“会话”或“工作单元”。这是一种方便的方法,可以抽象出您正在使用的任何数据库技术,而只需与一个非常通用的接口进行对话。因此,让我们将其重命名为ISession。这是我最近一直在做的模式。

    public class PeopleRepository {
      private readonly ISession session;
    
      public PeopleRepository(ISession session) {
        this.session = session;
      }
    
      public virtual IEnumerable<Person> Active() {
        return session.Find<Person>(p => p.Active).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
      }
    
      public virtual IEnumerable<Person> ByLastName(string name) {
        return session.Find<Person>(p => p.Active && p.LastName.StartsWith(lastName)).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
      }
    
      public virtual void DeletePerson(int personId) { 
        // We don't really delete people; we mark them as inactive.
        var person = session.Single<Person>(p => p.Id == personId);
        person.Active = false;
        session.Update(person);
      }
    }
    

    在此设置中,ISession 是指向数据存储的通用链接。但是,PersonRepository 非常特定于对 Person 对象执行的查询和操作类型。

    希望这会有所帮助。

    【讨论】:

    • 我现在也很喜欢这种方法。感谢您的比较和解释。
    【解决方案2】:

    我们目前正在将 EF 与 DDD 一起使用,但我不得不说,在其当前的实现中,EF 不太适合这种架构。主要问题是 EF 当前工作的唯一方法是让每个“实体”派生自特定于 EF 的基类。

    另一方面,关于存储库的全部意义在于抽象了数据访问技术。 DDD 背后的整个想法是域模型应该不受实施细节的限制,例如数据访问技术的选择。这意味着域对象应该被定义为 Persistence-Ignorant。

    换句话说:您不能将 EF“实体”用作域对象,因此在您的 DAL 中,您必须手动编写大量代码来映射到域对象和 EF“实体”。真的很快就累了。

    我肯定会认为在存储库上使用 IQueryable 是一种泄漏抽象,在 DDD 用语中它没有多大意义。如果域对象是内聚单元,那么仅从它们中选择某些“列”就没有多大意义。

    在 .NET 4.0 的 EF 中,我们将获得 Persistence Ignorance,因此未来应该会变得更好......

    【讨论】:

      【解决方案3】:

      这是一个示例:

      http://dataguidance.codeplex.com/

      【讨论】:

      • 这没有回答我的任何问题,实际上为我创造了更多。该数据访问指南项目也是基于 VS2010。
      猜你喜欢
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 2017-02-11
      相关资源
      最近更新 更多