我目前在我的主项目的单独项目中有一个数据层,包含EF和存储库模式。我正处于我想对查询实现分页和过滤的地步,并发现WebAPI具有OData查询支持。
这个问题可能只是因为我对此不熟悉,但如果我从项目的控制器中使用OData查询,是不是几乎不需要我的DAL项目?我之所以这么认为是因为存储库的接口必须公开IQueryable而不是List of Collections。
我有一个单独的数据层的原因是我正在尝试为我的公司创建一个Intranet系统,并且会有许多用户一次访问数据库。该层(我相信)将有助于将来扩展系统以及数据库请求,并通过创建方法库来消除控制器中的重复请求。
在存储库中公开IQueryables是不理想的?或者我不担心什么?
答案 0 :(得分:5)
您应该完全将您的实体集从DAL公开为 IQueryable 。
根据我的理解,您的DAL包装EF上下文并使用存储库模式,您将实体公开为IEnumerable / ICollection?如果是这种情况,那么当您将实体公开为IQueryable时,查询的执行将显着增加。
如果我从项目的控制器中使用OData查询,那么它不会 我的DAL项目几乎没必要?
您不应该让逻辑负责从/向控制器中的数据库接收/发送数据,因此您的DAL项目中的存储库仍然有用。
<强>阐释:强> 在性能方面,您应该记住,只要您在IQueryable上运行,您实际上是在运行SQL查询,一旦使用ToList()实现它,您就会对数据库执行请求并开始对数据进行操作来自系统内存。
关于从存储库中公开IQueryable: 与ICollection相比,您不仅可以获得更高的性能,还可以摆脱许多特定的数据提取方法(如GetAllActiveUsers,GetAllInactiveUsers等),从而可以向存储库的消费者查询特定数据,这在某些情况下可能会是一个问题,因为它可能会被他们滥用。但是,我不相信这是一个问题,因为我认为你并没有在一个庞大的开发团队中做出很大的应用。
示例强>: 所以,假设您有一个实体“User”和UserRepository类。您希望在Email属性中接收一组非空值的用户,因此您想出以下代码:
var users = _userRepository.Users.Where(x => x.Email != null).ToList();
如果将用户公开为IEnumerable / ICollection,则从数据库中返回所有用户,然后在系统内存中使用该集合搜索非空值的用户电邮属性。
在这种情况下,由EF生成并发送到数据库的查询看起来像SELECT * FROM [schema].[User]
如果将用户公开为IQueryable,则会返回电子邮件属性中已从数据库中的非空值的所有用户。在这种情况下,生成BY EF并发送到数据库的查询看起来像SELECT * FROM [schema].[User] WHERE [Email] IS NOT NULL