Entity Framework + DDD 相关问题

3
我发现在使用DDD风格模式下,使用EF的简单例子很难找到。这也是我第一次使用DDD,对解决方案布局和如何使用某些DDD模式有一些问题。
1)我看到的大多数关于使用Repository模式与EF的例子只显示了专门的模型接口,例如IContactRepository,然后是实现该接口的具体类型。理想情况下,我希望使用像IRepository这样的东西,它具有一组基本的CRUD操作功能。然后,如果需要,我可以创建特定的存储库,例如IContactRepository:IRepository,因为我的大多数模型不需要扩展。我是否走错了方向?可以给我提供这种实现方式的示例吗?
2)现在,我将我的解决方案分成以下三个项目:Models(包含我的EDM),Repositories和Services。这适合还是应该考虑其他布局方法?
3)我看到存储库有一个Query(Func<T>)/ Query()方法返回IQueryable的示例。这是令人不爽的,还是被禁止的?
3个回答

2

我希望回答第三个问题...

我认为这不是“臭”而是“懒”。以下是我在互联网上看到的典型“存储库”...

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);
}

据我所知,这不是一个仓库(repository),而是一个“会话(session)”或者“工作单元(unit of work)”。这是一种方便的方式,可以抽象出你正在使用的任何数据库技术,并且只需与一个极其通用的接口交互。因此,我们应该将其重命名为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 对象上执行的查询和操作类型。
希望这可以帮到您。

我现在也是这种方法的粉丝。感谢您的比较和解释。 - James Alexander

2
我们目前在使用EF和DDD,但我必须说,在其当前实现中,EF不太适合这种架构。主要问题是EF当前的工作方式是让每个“实体”派生自一个特定于EF的基类。
另一方面,仓储的整个重点是抽象数据访问技术。DDD背后的整个思想是领域模型应该不受实现细节的限制,例如数据访问技术的选择。这意味着定义域对象时应该使其持久性无关。
换句话说:您不能将EF“实体”用作域对象,因此在DAL中,您必须手动编写大量代码以将域对象映射到EF“实体”并从中映射出来。这很快就会变得疲倦。
我肯定认为在仓储上拥有IQueryable是一个泄漏的抽象,它在DDD术语中没有多少意义。如果域对象是内聚单元,那么仅从其中选择某些“列”就没有多少意义。
在.NET 4.0的EF中,我们将获得持久性无关性,因此未来应该会更好...

0

这并没有回答我的问题,反而让我有了更多的疑问。那个数据访问指南项目也是基于VS2010的。 - James Alexander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接