Repository模式 - 如何正确处理连接和复杂的查询? [英] Repository pattern - how to correctly handle JOINs and complex queries?

本文介绍了Repository模式 - 如何正确处理连接和复杂的查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有Repository模式的一个问题 - 如何执行几个仓库之间的连接操作。在这个项目中,我们使用MVC,EF,DDD。我知道,这样的问题在这里好几次,我在这一个以后引用这些问题。

之间的通用模型库(IRepository)和比库模型,我选择了具体的选项,因为我认为ORM(在本例中,EF)作为一种通用的存储库模式本身,所以它没有任何意义添加其他通用仓库,我们宁愿定制库域的需求。

问题是,我有几个(〜10)表,每个有许多行(百万),我需要进行连接,因此使用的IList或IEnumerable的是不是可行的选择。

我的理解(和我的观点)是IQueryable的不应该离开的库(DAL中会发生什么,应该留在DAL)。这将是简单的方式揭露IQueryable的,并在服务中使用它LINQ,但它强烈地违反了关注点分离,破坏了仓库的作用 - 在这种情况下,如确实库服务将做同样的事情。要挑几个,这些文章备份这个角度看(或者说信念):

要返回的IQueryable< T>或者没有返回的IQueryable< T>

<一个href=\"http://stackoverflow.com/questions/3039262/should-i-return-ienumerablet-or-iqueryablet-from-my-dal\">Should我回到了IEnumerable&LT; T&GT;或IQueryable的&LT; T&GT;从我DAL?

<一个href=\"http://www.shawnmclean.com/blog/2011/06/iqueryable-vs-ienumerable-in-the-repository-pattern/\">http://www.shawnmclean.com/blog/2011/06/iqueryable-vs-ienumerable-in-the-repository-pattern/

<一个href=\"http://blog.ploeh.dk/2012/03/26/IQueryableTisTightCoupling/\">http://blog.ploeh.dk/2012/03/26/IQueryableTisTightCoupling/

也有类似的问题和解决方案,例如<一href=\"http://stackoverflow.com/questions/20623022/how-to-join-multiple-tables-using-repository-pattern-entity-framework\">How联合多个表来使用存储库模式和放大器;实体框架的建议.INCLUDE(),但是这不是重负载表的选项,并在多个表的连接 - ?每个加盟,我们使用子查询来限制实际上加入了)

这个问题(答案和注释) - <一个href=\"http://stackoverflow.com/questions/10288695/how-can-i-query-cross-tables-with-repository-pattern\">How我可以查询交叉表与存储库模式 - 基本上表明基于任务的分化:?对于连接的查询创建一个存储库,而正规库与每个实体操纵

我看到我们有下列选项:


  1. 揭露的IQueryable以及执行服务JOIN复杂的查询;我由衷地感到它的反模式,我不喜欢这样。

  2. 请不要使用存储库这些〜10桌,并执行服务查询;一些文章建议使用EF足够(例如<一个href=\"http://stackoverflow.com/questions/7291692/is-it-okay-to-bypass-the-repository-pattern-for-complex-queries\">Is它没关系绕过存储库模式对于复杂的查询?),我不与赞同。

  3. 使用基于任务的分化,不限制存储库1:1回购:实体(我赞成这个选项)

  4. 完全不同的东西?

所以 - 你会建议?一次又一次,谢谢你。


解决方案

  1. 表示泄漏到持久性应用 - 反模式,spaghetti- code

  2. 从(1)究竟有什么不同?还是同样的问题。

  3. 有点接近...

  4. 使用的查询对象格局。封装的复杂查询在驻留仓库旁边一个基于任务的对象。它可以返回的DTO的观点,而不是域对象进行了优化。

  5. 依托倚重QO将带领您到一个架构,称为CQRS - 命令查询责任分离

一件事。没有1:1匹配的实体:回购。只有骨料应该有一个仓库,并不是每一个单一的实体。

I have a problem with Repository pattern - how to perform JOIN operations between several repositories. In this project, we use MVC, EF, DDD. I'm aware that this kind of question was here several times, I reference these questions later in this one.

Between generic repository model (IRepository) and specific repository model, I chose specific option, since I consider ORM (in our case EF) as a generic repository pattern itself, so it doesn't make sense to add another generic repository and we'd rather tailor the repository to the domain needs.

The problem is that I have several (~ 10) tables, each with many rows (millions), and I need to perform JOINs, so using IList or IEnumerable isn't viable option.

My understanding (and my perspective) is that IQueryable shouldn't leave the repository ("What happens in DAL, should stay in DAL."). It would be way simpler to expose IQueryable and use it in LINQ in service, but it strongly violates separation of concerns and undermines role of repositories - in such case, service will be doing the same thing as repository does. To pick a few, these articles back up this perspective (or rather conviction):

To return IQueryable<T> or not return IQueryable<T>

Should I return IEnumerable<T> or IQueryable<T> from my DAL?

http://www.shawnmclean.com/blog/2011/06/iqueryable-vs-ienumerable-in-the-repository-pattern/

http://blog.ploeh.dk/2012/03/26/IQueryableTisTightCoupling/

There are also similar questions and solutions, e.g. How to join Multiple tables using Repository Pattern & Entity Framework? that suggest .Include(), but this is not an option for heavy loaded tables and joins across many tables - with each JOIN, we use subselects to limit what's actually joined).

This question (the answer and comments) - How can I query cross tables with Repository Pattern? - basically suggests task-based differentiation: creating one Repository for queries with JOINS, and "regular" Repositories for manipulation with each entity.

I see we have these options:

  1. Exposing IQueryable and performing JOIN complex queries in services; I sincerely feel it's anti-pattern, I don't like that.
  2. Don't use Repository for these ~ 10 tables and perform queries in services; some articles suggested that using EF is enough (e.g. Is it okay to bypass the repository pattern for complex queries?), I don't concur with that.
  3. Use task-based differentiation, don't limit repositories 1:1 repo:entity (I'm in favor of this option)
  4. Something completely different?

So - what would you suggest? Again and again, thank you.

解决方案

  1. means leaking persistence into application - antipattern, spaghetti-code.
  2. how it differs from (1) exactly? Still the same issue.
  3. a bit closer...
  4. Use Query Object pattern. Encapsulate your complex query in a task-based object that resides alongside repositories. It can return DTOs optimized for view rather than domain objects.
  5. Relying heavily on QO will lead you to an architecture called CQRS - Command-Query Responsibility Segregation.

One more thing. There is not 1:1 match for entity:repo. Only Aggregates should have a repository, not every single entity.

这篇关于Repository模式 - 如何正确处理连接和复杂的查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆