具有不同属性传递动态表达式的IQueryable扩展方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有不同属性传递动态表达式的IQueryable扩展方法相关的知识,希望对你有一定的参考价值。

我有以下4种方法,我想为其创建2个扩展方法(一种用于布尔型单个过滤器,一种用于两个int),这将在EF Core 3.1中执行]]

var query = context.Listings.AsQueryable();


if (request.HasBalcony.HasValue)

    query = query.Where(x => x.HasBalcony == request.HasBalcony);


if (request.HasElevator.HasValue)

    query = query.Where(x => x.HasElevator == request.HasElevator);

我只是想针对上述布尔开关执行上述操作

query = query.ApplyBoolFilter(x=>x.HasBalcony, request.HasBalcony);
query = query.ApplyBoolFilter(x=>x.HasElevator, request.HasElevator);
query = query.ApplyBoolFilter(x=>x.HasElevator, null); //this should not apply any filters

替换上述方法的方法

public static IQueryable<Listing> ApplyBoolFilter(this IQueryable<Listing> query, bool? value, Expression<Func<Listing, bool>> filter)

    return //not sure what goes here or the parameters

然后

if(request.MaxBedrooms.HasValue || request.MinBedrooms.HasValue)

    if(request.MaxBedrooms.HasValue && request.MinBedrooms.HasValue)
    
        query = request.MinBedrooms == request.MaxBedrooms ? 
            query.Where(x => x.BedroomsAvailable == request.MinBedrooms) 
            : query.Where(x => x.BedroomsAvailable >= request.MinBedrooms && x.BedroomsAvailable <= request.MaxBedrooms);
    
    else if(request.MaxBedrooms.HasValue)
    
        query = query.Where(x => x.BedroomsAvailable <= request.MaxBedrooms);

    
    else if (request.MinBedrooms.HasValue)
    
        query = query.Where(x => x.BedroomsAvailable >= request.MaxBedrooms);

    


if (request.MaxParkingSpots.HasValue || request.MinParkingSpots.HasValue)

    if (request.MaxParkingSpots.HasValue && request.MinParkingSpots.HasValue)
    
        query = request.MinParkingSpots == request.MaxParkingSpots ? 
            query.Where(x => x.ParkingSpotsIncluded == request.MinParkingSpots) 
            : query.Where(x => x.ParkingSpotsIncluded >= request.MinParkingSpots && x.ParkingSpotsIncluded <= request.MaxParkingSpots);
    
    else if (request.MaxParkingSpots.HasValue)
    
        query = query.Where(x => x.ParkingSpotsIncluded <= request.MaxParkingSpots);

    
    else if (request.MinParkingSpots.HasValue)
    
        query = query.Where(x => x.ParkingSpotsIncluded >= request.MaxParkingSpots);

    


以上切换到扩展方法

query = query.ApplyRangeFilter(x=>x.BedroomsAvailable, request.MaxBedrooms, request.MinBedrooms);
query = query.ApplyRangeFilter(x=>x.ParkingSpotsIncluded, request.MinParkingSpots, request.MaxParkingSpots);

替换上述方法的方法

public static IQueryable<Listing> ApplyRangeFilter(this IQueryable<Listing> query, int? minValue int? maxValue, Expression<Func<Listing, int>> filter)

   return //not sure what goes here or the parameters

我有以下4种方法,我想为其创建2个扩展方法(一种用于布尔型单个过滤器,一种用于两个int),这将使用EF Core 3.1 var query = ...]执行] >

要实现这一点:

query = query.ApplyBoolFilter(x=>x.HasBalcony, true);

true值取决于用户输入(它不是const),

尝试此代码:

        public static IQueryable<Listing> ApplyBoolFilter(this IQueryable<Listing> query, Expression<Func<Listing, bool>> filter, bool? value)
        
            if (value == null)
                return query;
            return query.Where(i => filter(i) == value);
        

并获得此结果:

query = query.ApplyRangeFilter(x=>x.BedroomsAvailable, request.MaxBedrooms, request.MinBedrooms);

尝试以下代码:


        public static IQueryable<Listing> ApplyBoolFilter(this IQueryable<Listing> query, Expression<Func<Listing, bool>> select, int? minValue, int? maxValue)
        
            if (minValue is null && maxValue is null)
                return query;
            return query.Where(i => minValue.HasValue ? select(i) >= minValue.Value : maxValue.HasValue ? select(i) >= maxValue.Value : true)
        

答案

要实现这一点:

以上是关于具有不同属性传递动态表达式的IQueryable扩展方法的主要内容,如果未能解决你的问题,请参考以下文章

深入LINQ | 揭开IQueryable的面纱

以更好的性能将 IQueryable<X> 转换为 IQueryable<Y>

JMeter 不同线程组间变量传递

具有嵌套属性的动态 linq 表达式树

如何动态传递数据库连接属性以连接到 pentaho 中的不同数据库

动态创建具有不同数量的属性和值的谓词