将OData语法与WebAPI和DAL一起使用

时间:2015-04-28 17:22:21

标签: c# entity-framework asp.net-web-api odata

我目前在我的主项目的单独项目中有一个数据层,包含EF和存储库模式。我正处于我想对查询实现分页和过滤的地步,并发现WebAPI具有OData查询支持。

这个问题可能只是因为我对此不熟悉,但如果我从项目的控制器中使用OData查询,是不是几乎不需要我的DAL项目?我之所以这么认为是因为存储库的接口必须公开IQueryable而不是List of Collections。

我有一个单独的数据层的原因是我正在尝试为我的公司创建一个Intranet系统,并且会有许多用户一次访问数据库。该层(我相信)将有助于将来扩展系统以及数据库请求,并通过创建方法库来消除控制器中的重复请求。

在存储库中公开IQueryables是不理想的?或者我不担心什么?

1 个答案:

答案 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();
  1. 如果将用户公开为IEnumerable / ICollection,则从数据库中返回所有用户,然后在系统内存中使用该集合搜索非空值的用户电邮属性。 在这种情况下,由EF生成并发送到数据库的查询看起来像SELECT * FROM [schema].[User]

  2. 如果将用户公开为IQueryable,则会返回电子邮件属性中已从数据库中的非空值的所有用户。在这种情况下,生成BY EF并发送到数据库的查询看起来像SELECT * FROM [schema].[User] WHERE [Email] IS NOT NULL