我观看了this视频并阅读了this博客文章。这篇文章中有些东西让我困惑;帖子的最后一部分。在最后一部分中,Mosh强调,Repository永远不应该返回IQueryable,因为它会导致性能问题。但我读到的内容听起来很矛盾。
这是令人困惑的部分:
IEnumerable:在从数据库查询数据时,IEnumerable在服务器端执行select查询,在客户端加载内存中的数据,然后过滤数据。因此,做更多的工作,变得缓慢。
IQueryable:在从数据库查询数据时,IQueryable在服务器端使用所有过滤器执行select查询。因此,工作量减少,变得快速。
this is another answer关于存储库模式中的IQueryable与IEnumerable。
这些与莫什的建议相反。如果这些都是真的,为什么我们不应该使用IQueryable而不是IEnumerable。
还有别的,我们想要使用OData的情况如何;如您所知,在使用OData查询时,最好使用IQueryable而不是IEnumerable。
还有一件事,使用OData查询电子商务网站API是好还是坏。
请让我知道你的意见。
谢谢
莫什试图说的是:
“我们正在使用存储库模式来实现封装”。
当我们返回IQueryable时,随着我们的应用程序的增长,可能是其他人想查询我们的查询!这是使用IQueryable而不是IEnumerable的有害部分(在所有情况下都不错,但在这种情况下,这是一个非常糟糕的做法)。
看看他的例子:
var orders = context.Orders
.Include(o => o.Details)
.ThenInclude(d => d.Product)
.Where(o => o.CustomerId == 1234);
这里我们直接使用没有存储库模式的DbContext。当您的存储库方法返回IQueryable时,其他人将获得IQueryable并在其上构建查询。这是结果:
var orders = repository.GetOrders()
.Include(o => o.Details)
.ThenInclude(d => d.Product)
.Where(o => o.CustomerId == 1234);
这里唯一的区别是,在第一个查询中我们使用context.Orders,在第二个查询中我们使用repository.GetOrders()。这在查询上是一个很大的重复,因此它也是一个糟糕的性能损失,并且你知道没有问题得到解决。
这就是他说的原因:
您的存储库应该返回域对象。因此,GetOrders()方法应返回IEnumerable。有了这个,第二个例子可以重写为:
var orders = repository.GetOrders(1234);
如果使用OData作为查询系统,我们在同一页面;因为我们的数据将由第三人查询而不知道我们的数据检索模式。