entity-framework - 使用 DDD 和 IoC 为 EF4 实现存储库

标签 entity-framework entity-framework-4 domain-driven-design repository inversion-of-control

我想我在绕圈子。

我正在使用 EF4 和 POCO(数据库优先)和 IoC 开发 MVC 3 解决方案。我的存储库和 UoW 模式大多来自 this articlethis article .

我的解决方案由以下项目组成:

实现:

  • 演示文稿(MVC 网站)
  • 领域服务(业务层)
  • 域存储库(数据访问)
  • 域上下文(我的 EF4 edmx 和生成的上下文)
  • 领域模型(我的 EF4 生成的 POCO)

  • 接口(interface):
  • 域服务接口(interface)(业务层接口(interface))
  • 域存储库接口(interface)(数据访问接口(interface))
  • 域上下文接口(interface)(生成的 EF4 上下文的接口(interface))

  • 最后,将一切联系在一起的 IoC 项目。

    如果您在第一篇文章中注意到,作者提到从域服务中删除对 ObjectSet 的依赖。我假设这是为了可测试性。但是,问题在于它阻碍了从域服务执行复杂查询的能力,因为 IObjectSet 和 IEnumerable(由存储库上的大多数方法返回)不会为复杂查询保留方法。

    这是否意味着我应该在我的存储库中进行复杂的查询?我应该放弃像 public T Single(Expression<Func<T, bool>> where) 这样的方法吗?并坚持使用 public T GetUserById(int id) 之类的方法?

    如果不是这种情况,那么我该如何做复杂的查询 such as this在我的服务层?

    看看我上面的解决方案大纲和我的问题,我是在朝着正确的方向前进,还是在为自己制造问题?

    提前致谢。

    最佳答案

    这是主观/意见问题,但您可以让您的存储库返回 IQueryable<T> ,那么您可以像这样在您的服务中执行“复杂查询”:

    return _repository // IRepository<T>
              .Find() // IQueryable<T>
              .Where(someComplexPredicate) // IQueryable<T>
              .SingleOrDefault(); // T
    
    ObjectSet<T> : IQueryable<T> ,这使得这成为可能。

    如果你想开始做ObjectSet<T> - 您服务中的特定内容,您有两种选择:
  • 曝光ObjectSet<T> -特定方法作为存储库接口(interface)上的方法
  • 使用 IQueryable<T>ObjectSet<T> 进行“软转换”的扩展方法(例如 var objSet = source as ObjectSet<T> )。

  • 始终尝试使用选项 1。

    完美的例子是急切加载。有一种方法叫做 IncludeObjectContext<T> , 所以如果你使用 IQuerayable<T>在您的存储库中,您如何急切加载?

    由于Include需要一个“魔术字符串”,您可以在 Find 中接受它存储库中的方法,例如:
    return _repository // IRepository<T>
              .Find("Product.Orders") // IQueryable<T>
              .Where(someComplexPredicate) // IQueryable<T>
              .SingleOrDefault(); // T
    

    幸运的是,他们在 EF CTP5 中引入了强类型 Include有效IQueryable<T> ,所以我在切换时不必执行上述操作。

    所以正如我所说,最好的办法是在你的 Repository 接口(interface)上公开方法。但是需要进行权衡 - 接口(interface)应该是服务的“契约(Contract)”或“定义”,而不是实现。所以 EF 特定的事情应该通过扩展方法来完成。一般的事情可以通过存储库接口(interface)完成。

    关于entity-framework - 使用 DDD 和 IoC 为 EF4 实现存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5241377/

    相关文章:

    asp.net-mvc-2 - 基于两个属性的自定义模型验证。一个影响另一个

    c# - 使用Entity Framework 4.0时如何更新不同表的相关条目?

    domain-driven-design - 在事件溯源中如何处理一致性违规?

    oop - DDD - 补充骨料根的水分?

    domain-driven-design - 偶尔连接CQRS系统

    c# - 如何在不将第一个实体插入 Entity Framework C# 中的数据库的情况下将实体 ID 分配给另一个实体?

    c# - 将扩展方法限制为仅针对 EF 实体

    c# - 在 Visual Studio 2015 中使用 ADO.NET 和 MySQL

    entity-framework-4 - 禁用 Entity Framework 4.1 对所有实体的乐观并发检查

    c# - Entity Framework 中的一对多关系导致异常