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

chi*_*kid 4 c# entity-framework odata asp.net-web-api

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

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

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

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

And*_*w B 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();
Run Code Online (Sandbox Code Playgroud)
  1. 在将用户公开为IEnumerable/ICollection的情况下,您将从数据库中返回所有用户,然后在系统内存中使用该集合搜索具有非零值Email属性的用户.在这种情况下,由EF生成并发送到数据库的查询看起来像SELECT * FROM [schema].[User]

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

  • 我知道您希望将发送/接收逻辑分开,但至少在我看来,当您公开 IQueryable 时,这意味着我的控制器实际上会进行查询,对吗?我只是看起来我的 DAL 就像一个直通隧道,传递我可以在我的控制器中声明的 IQueryable 以及我的查询参数? (2认同)
  • 您的控制器将只是客户端,告诉您的DAL类似"嘿,我看到您有关于所有用户的信息,给我带有Name = John的信息",但事实上DAL负责执行查询.您的控制器不是"声明"IQueryable,而是使用您的查询参数扩展DAL公开的IQueryable实体,并要求DAL执行它. (2认同)
  • 当然会有效.但是,请记住,通用存储库被许多人视为反模式,因为它为每个实体定义了相同的beaviour,而业务逻辑通常要求某些实体具有不同的行为(例如,您可能希望提供删除特定实体的能力逻辑上数据库中的实体 - 通过更改一些标志来告知记录是否仍处于活动状态,而对于其他实体,您希望删除是物理的).在您的情况下,这可能不是问题,如果您是唯一的代码用户并且您的应用程序相对较小. (2认同)