建立 IQueryable 包括基于条件的附加表

Posted

技术标签:

【中文标题】建立 IQueryable 包括基于条件的附加表【英文标题】:Build up IQueryable including additional tables based on conditions 【发布时间】:2021-10-28 17:25:57 【问题描述】:

我遇到了一个问题,我们需要创建一个复杂的 IQueryable 以提高效率。

只有在过滤其中的列时才应包含 2 个表。

我的确切情况很难解释,所以我想我可以用汽车的例子来说明它。

如果我有这样的CarFilter 类:

public class CarFilter

    public string BrandName  get;set; 
    public decimal SalePrice get; set; 

假设我们有一个汽车销售查询:

var info = from car in cars
           from carSale in carSales on carSale.BrandId == car.BrandId && car.ModelId == carSale.ModelId
           from brand in carBrands on car.BrandId == brand.BrandId
           select car

 var cars = info.ToList();

假设这是一个巨大的查询,当我们查看汽车和销售以及相关品牌时,它会返回 100,000 行。

用户只想查看汽车的详细信息,其他2个表格用于过滤目的。

所以如果用户只想看福特汽车,我们上面的逻辑是没有效率的。我们和CarBrand一样无缘无故地加入了巨大的汽车销售表,因为用户不关心那里的任何东西。

我的问题是,如果确实需要,我如何才能仅在 IQueryable 中包含表格?

因此,如果我的过滤器中有BrandName,我将包含CarBrand 表,如果没有,则不包含。

使用此示例,我唯一需要两个表的情况是用户同时指定 BrandNameSalePrice

语义在这里并不重要,即返回的记录数受到连接等的影响,我正在寻求有关方法的帮助

我正在使用 EF Core

保罗

【问题讨论】:

【参考方案1】:

复杂的过滤很常见。只需在需要时加入即可。

var query = cars;

if (filter.SalePrice > 0)

    query =  
        from car in query
        join carSale in carSales on new  car.BrandId, car.ModelId  equals new  carSale.BrandId, carSale.ModelId 
        where carSale.Price >= filter.SalePrice
        select car;


if (!filter.BrandName.IsNullOrEempty())

    query = 
        from car in query
        join brand in carBrands on car.BrandId equals brand.BrandId
        where brand.Name == filter.BrandName
        select car;


var result = query.ToList();

【讨论】:

我怎样才能自定义我的选择语句? IE。从表中选择不同的字段?例如选择 car.BrandId 和 Brand.Name? 嗯,这是不同的问题。而我没有得到它。你期待哪个结果?最好为此创建新的 SO 问题。

以上是关于建立 IQueryable 包括基于条件的附加表的主要内容,如果未能解决你的问题,请参考以下文章

如何将两个连接表中的 IQueryable LINQ 结果返回到 List<string> 中?

SQL:按条件从不同表中按计数排序

我可以克隆一个 IQueryable 以在另一个 DbContext 的 DbSet 上运行吗?

使用IQueryable扩展方法实现复杂查询条件

在 NET.Core 中构建多/单条件搜索功能(IQueryable 或 IEnumerable)

我正在寻找一种从字符串构建 IQueryable 查询的方法