gpt4 book ai didi

c# - Web Api $extend IQueryable 带过滤器

转载 作者:行者123 更新时间:2023-11-30 20:21:20 25 4
gpt4 key购买 nike

我有一个设置,其中我有一个返回的 WebApi OData 服务:客户。返回客户的代码是:

public IHttpActionResult GetCustomers(ODataQueryOptions<Customer> queryOptions)
{
return Ok(context.Customers.Where(i => i.IsActive).AsQueryable());
}

因此 GetCustomers 方法返回所有活跃客户的 IQuerable 结果。出于历史目的,我们将所有客户都留在数据库中,但是当客户被删除时,我们将 IsActive 字段设置为 false。

OData 设置是使用简单的 builder.EntitySet 创建的,用于为实体构建 Url。

EntitySetConfiguration<Customer> customers = builder.EntitySet<Customer>("customers");

这完美无缺。我有一个 Angular 前端,它使用 $http 调用来接收客户等。

但是,客户可以在数据库中包含相关联系人。为了在 Angular 前端获取联系人,我使用了 OData 的 $extend 功能:

odata/customers?$expand=contacts

这也很好用。我收到了所有相关联系人的客户。但是,正如您所猜到的,我只想接收应返回具有 IsActive 的联系人。 IQueryable 功能返回所有结果。

我知道我可以使用单独的 Odata 调用来获取联系人,但我真的很想使用 $expand 功能在一次调用中获取所有数据。我知道我也可以在客户端进行过滤(使用:$filter)。但我想在 WebApi 部分正确设置它,因此客户端不必关心过滤非事件结果。

我似乎无法弄清楚如何正确地实现这一点。有人可以帮助我走上正轨吗?

最佳答案

EntityFramework.DynamicFilters是我所知道的最伟大的 Entity Framework 工具之一。它跳入了经常请求但直到 EF6 从未实现过滤 Incude 功能的空白。它依赖于 EF 的拦截 API,并在公开非常简单的界面的同时完成修改表达式的繁重工作。

在你的情况下,你可以做的是这样的:

using EntityFramework.DynamicFilters;

// In OnModelCreating (DbContext)
modelBuilder.Filter("CustomerActive", (Customers c) => c.IsActive);

就是这样!现在,在查询 Customers 的任何地方,无论是直接查询、通过导航属性还是在 Include 中查询,谓词都将添加到查询中。

您想要所有客户吗?您可以通过执行以下操作简单地关闭每个上下文实例的过滤器

context.DisableFilter("CustomerActive");

到目前为止,我只发现了一个故障(或警告)。如果有两个实体,ParentChild 并且 Parent 上有一个不返回任何记录的过滤器,那么这个查询 .. .

context.Children.Include(c => c.Parent)

... 不返回任何内容。但是,从查询的形式来看,我希望它返回父级为空的 Child 实体。

这是因为在 SQL 中,ParentChild 之间有一个 INNER JOIN 和一个关于 Parent 的谓词计算结果为 falseOUTER JOIN 会给出预期的行为,但我们当然不能要求这个库变得那样聪明。

关于c# - Web Api $extend IQueryable 带过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34134300/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com