OData 和存储库模式中的 IEnumerable 与 IQueryable

5 ienumerable iqueryable repository-pattern odata

我观看了这个视频并阅读了这篇博文。这篇文章中有一些东西让我感到困惑;帖子的最后一部分。在最后一部分 Mosh 强调,Repository 永远不应该返回 IQueryable,因为它会导致性能问题。但我读到了一些听起来自相矛盾的东西。

这是令人困惑的部分:

IEnumerable:在从数据库查询数据时,IEnumerable 在服务器端执行选择查询,在客户端加载内存中的数据,然后过滤数据。因此做更多的工作并且变得缓慢。

IQueryable:在从数据库查询数据时,IQueryable 使用所有过滤器在服务器端执行选择查询。因此,工作量减少,速度变快。

这是关于存储库模式中 IQueryable 与 IEnumerable 的另一个答案。

这些与 Mosh 的建议相反。如果这些都是真的,为什么我们不应该使用 IQueryable 而不是 IEnumerable。

还有别的,我们想使用 OData 的情况呢?如您所知,在通过 OData 进行查询时,最好使用 IQueryable 而不是 IEnumerable。

还有一件事,使用 OData 查询电子商务网站 API 是好是坏。

请让我知道你的意见。

谢谢

jga*_*fin 1

存储库永远不应该返回IQueryable. 但不是因为性能。这是由于复杂性。存储库旨在降低业务层的复杂性。

购买暴露并IQueryable通过两种方式增加复杂性:

  • 您将持久性知识泄漏到业务领域。为了编写有效的查询,您必须了解有关底层 Linq to Sql 提供程序的一些事情。
  • 您必须设计业务实体以便可以查询它们(即不是纯业务实体)。

例子:

var blockedUsers = _repository.GetBlockedUsers();

//vs

var blockUsers = _dbContext.Users.Where(x => x.State == 1);
Run Code Online (Sandbox Code Playgroud)
var user = _repos.GetById(1);
//and an enum is used internally in the user class
user.Block(); 
_repos.Update(user);

// vs 
var user = _dbContext.Users.FirstOrDefault(x => x.Id == 1);
user.State = 1;
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

通过将所有内容包装在存储库后面,您可以以一种易于使用的方式设计业务实体(子实体、枚举、日期管理等)。您设计存储库,以便可以有效地存储这些实体。没有任何妥协,代码更容易维护。

关于 OData:不要使用存储库模式。在这种情况下它不会增加任何价值。

如果你坚持在你的业务领域使用IQueryable,就不要使用存储库模式。它只会使事情变得复杂,而不会增加任何价值。

最后:

使用正确设计的存储库的业务逻辑更容易测试(单元测试)。混合 LINQ 和业务逻辑的代码必须始终进行集成测试(针对数据库),因为 Linq to Sql 与 Linq to Objects 不同。