ASP.Net 核心 OData - 按嵌套匹配数过滤
ASP.Net Core OData - filter by number of nested matching
我有一个根 Company
实体,有 CompanyType
个子实体。我想过滤所有提供类型的公司。可以在纯 SQL
中创建这样的过滤器
SELECT Companies.Id, Companies.Name
FROM Companies
JOIN (
SELECT CompanyTypes.CompanyId FROM CompanyTypes
WHERE CompanyTypes.CompanyTypeId IN (123, 456, 789, 555)
GROUP BY CompanyId
HAVING COUNT(*) = 4
) Types ON Companies.ID = Types.CompanyID
也可以使用 linq to sql
创建这样的过滤器
var typeIds = new[] { 123, 456, 789, 555 };
var companies = await EFContext.Companies.Where(company => company.CompanyTypes.Count(type => typeIds.Contains(type.CompanyTypeId)) == typeIds.Length).ToListAsync();
有没有办法使用 odata 语法编写这样的查询?我试过这个
companyTypeIds/any(i: i eq 123) and companyTypeIds/any(i: i eq 456) and companyTypeIds/any(i: i eq 789) and companyTypeIds/any(i: i eq 555)
它给出了预期的结果,但底层查询不同,并且当条件数量增加时它变得非常慢。有没有办法让它像提供的 SQL 查询一样更有效率?后端正在使用 ASP.Net Core 6、EF Core 6、ASP.Net Core OData 8(目前最新)。
拥有要转换为 OData 查询的 SQL 和 LINQ 使这成为一个更容易的命题,WHERE IN ()
与 HAVING COUNT(*) = 4
都可以在 OData 中实现v4.01 和最近改进的支持
Adding support for $count segment in $filter collections in OData WebAPI
In OData core v7.9.0 we added improved support for $count segment in $filter collection properties.
$filter=navProp/$count($filter=prop gt 1) gt 2
$filter=collectionProp/$count($filter=prop gt 1) gt 2
对于此 LINQ:
var typeIds = new[] { 123, 456, 789, 555 };
var companies = await EFContext.Companies.Where(company =>
company.CompanyTypes.Count(type => typeIds.Contains(type.CompanyTypeId)) ==
typeIds.Length).ToListAsync();
以下应该适用于您的查询:
~/Companies?$filter=CompanyTypes/$count($filter=CompanyTypeId in (123, 456, 789, 555) eq 4)
我有一个根 Company
实体,有 CompanyType
个子实体。我想过滤所有提供类型的公司。可以在纯 SQL
SELECT Companies.Id, Companies.Name
FROM Companies
JOIN (
SELECT CompanyTypes.CompanyId FROM CompanyTypes
WHERE CompanyTypes.CompanyTypeId IN (123, 456, 789, 555)
GROUP BY CompanyId
HAVING COUNT(*) = 4
) Types ON Companies.ID = Types.CompanyID
也可以使用 linq to sql
创建这样的过滤器var typeIds = new[] { 123, 456, 789, 555 };
var companies = await EFContext.Companies.Where(company => company.CompanyTypes.Count(type => typeIds.Contains(type.CompanyTypeId)) == typeIds.Length).ToListAsync();
有没有办法使用 odata 语法编写这样的查询?我试过这个
companyTypeIds/any(i: i eq 123) and companyTypeIds/any(i: i eq 456) and companyTypeIds/any(i: i eq 789) and companyTypeIds/any(i: i eq 555)
它给出了预期的结果,但底层查询不同,并且当条件数量增加时它变得非常慢。有没有办法让它像提供的 SQL 查询一样更有效率?后端正在使用 ASP.Net Core 6、EF Core 6、ASP.Net Core OData 8(目前最新)。
拥有要转换为 OData 查询的 SQL 和 LINQ 使这成为一个更容易的命题,WHERE IN ()
与 HAVING COUNT(*) = 4
都可以在 OData 中实现v4.01 和最近改进的支持
Adding support for $count segment in $filter collections in OData WebAPI
In OData core v7.9.0 we added improved support for $count segment in $filter collection properties.$filter=navProp/$count($filter=prop gt 1) gt 2 $filter=collectionProp/$count($filter=prop gt 1) gt 2
对于此 LINQ:
var typeIds = new[] { 123, 456, 789, 555 };
var companies = await EFContext.Companies.Where(company =>
company.CompanyTypes.Count(type => typeIds.Contains(type.CompanyTypeId)) ==
typeIds.Length).ToListAsync();
以下应该适用于您的查询:
~/Companies?$filter=CompanyTypes/$count($filter=CompanyTypeId in (123, 456, 789, 555) eq 4)