在OData和Repository Pattern中IEnumerable vs IQueryable

问题描述 投票:2回答:1

我观看了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是好还是坏。

请让我知道你的意见。

谢谢

odata ienumerable repository-pattern iqueryable
1个回答
1
投票

莫什试图说的是:

“我们正在使用存储库模式来实现封装”。

当我们返回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作为查询系统,我们在同一页面;因为我们的数据将由第三人查询而不知道我们的数据检索模式。

© www.soinside.com 2019 - 2024. All rights reserved.