C# 用webapi进行过滤

C# 用webapi进行过滤,c#,entity-framework,asp.net-web-api,asp.net-core,C#,Entity Framework,Asp.net Web Api,Asp.net Core,我有一个带有多个Web API控制器的应用程序,现在我有一个要求,就是能够通过对象属性过滤得到结果。我一直在考虑使用,但由于以下几个原因,我不确定它是否适合: Web API控制器不能直接访问DataContext,而是通过“域”层从数据库获取数据,因此无法查看实体框架模型 结合第一项,WebAPI处理在域层生成的轻量级DTO模型对象。这实际上隐藏了EF模型。这里的问题是,我希望在数据库中执行这些查询,但当Web API方法从域层获取集合时,集合中的所有对象都已映射到这些DTO对象,因此我不知道

我有一个带有多个Web API控制器的应用程序,现在我有一个要求,就是能够通过对象属性过滤得到结果。我一直在考虑使用,但由于以下几个原因,我不确定它是否适合:

  • Web API控制器不能直接访问
    DataContext
    ,而是通过“域”层从数据库获取数据,因此无法查看实体框架模型
  • 结合第一项,WebAPI处理在域层生成的轻量级DTO模型对象。这实际上隐藏了EF模型。这里的问题是,我希望在数据库中执行这些查询,但当Web API方法从域层获取集合时,集合中的所有对象都已映射到这些DTO对象,因此我不知道当对象以这种方式从EF中删除时,OData过滤器如何能够完成其工作
  • 这一点可能是最重要的:我们真的不想允许对我们的Web API/数据库进行任意查询。我们只是想利用这个OData库来避免编写我们自己的过滤器,并为我们的一个Web API端点可能返回的每种类型的对象编写过滤器解析器/构建器

  • 基于#3,我是否走错了方向?如果没有,我们是否能够使用这个OData库而不必对Web API和EF的交互方式进行重大重构?

    我没有OData方面的经验,但从我所看到的情况来看,它的设计目的是提供一个上下文,并管理这些模型的交互和返回。我绝对不喜欢以任何形式将实体返还给客户

    这是一个丑陋的情况,但当面对这一点,我的第一个行动方针是推回客户,以证明他们的搜索需求。默认的请求几乎总是“好吧,能够搜索所有东西会很好。”我的回答是,我不想知道你想要什么,我想知道你需要什么,因为我不想给你一把装了子弹的枪让你自己开枪,然后让你怪我,因为系统停止运转了。如果搜索过于开放,它将是一个巨大的性能杀手。当用户只需要25%的场景时,很难测试准确性/相关性,并有效地索引100%的可能搜索案例。如果客户不能告诉你他们需要什么搜索,只是因为他们可能需要而想要一切,那么他们现在还不需要

    就我个人而言,我坚持使用特定的搜索DTO,并将其转换为linq表达式

    如果我面临实施类似内容的困难要求,我会:

  • 尝试推动在与实时数据库同步的报告副本上完成这些搜索/报告。(当一些白痴管理者启动一些古怪的非索引搜索条件时,可以最大限度地减少出血,这样就不会占用人们试图工作的生产数据库。)
  • 创建一个新的特定于搜索的有界DbContext,使用单独的实体定义进行搜索,这些实体定义只公开表示搜索条件和ID的最小属性
  • 将此绑定上下文挂接到API和OData中。它将返回“搜索结果”。当用户选择搜索结果时,对API使用ID加载适用的域,或启动操作等

  • 第一。是可选的,这是一个很好的选择,提供了他们可以在复制之前不“看到”更新的搜索条件。(即几秒钟到几分钟,具体取决于复制策略/大小)通常这些搜索用于报告类型查询,因此我会将它们与用户使用的正常日常搜索选项分开。(即高级搜索选项等。)

    据我所知,OData允许您将“查询”传递到web服务端点并接收数据集。但是,您希望在Web API控制器和域层之间过滤数据。为什么不将LINQ表达式传递到域层?如果模型不是1:1,您可以通过mapper进行转换。您可以将查询转换为yr Dao,然后在服务中将它们映射到Dto。但是,如果您能够从数据库中获取所有项目,然后对其进行查询,那么这是一个性能问题。还要创建某种类型的筛选器对象。@alans听起来似乎可以工作,但是我首先要如何让LINQ表达式传递到域层呢?我可以从ODataURL查询中获取它吗?@KyleV。也许这可能是太多的编码。但这里有一个更简单的想法:从域层,通过Automapper的返回DTO
    IQueryable
    。然后,将OData的ODataQueryOptions的ApplyTo用于可查询的DTO。然后从那里获取结果。当您坚持使用特定的搜索DTO时,如何设计Web API端点以基于其中一个DTO的一个或多个属性进行过滤?我不知道如何表达搜索条件,而这正是OData通过其
    http://localhost:5000/odata/Books?$filter=Price le 50
    query语法。当客户端设置特定的搜索场景时,特定的DTO适用。即,用户选择一个场景,如果有适用的参数。也就是说,在订单屏幕上,他们可以按订单或类似“过期订单”的搜索进行搜索。对于用户来说,基本上什么是有用的场景。对于查询表达式的更多开放式搜索(想想你的gt/gte/lt/lte和/或/或/不选择你的字段等),这个更高级的选项将涉及使用OData或自定义筛选之类的东西。我的主要目的是让这种搜索远离日常使用。