具有针对不同属性传递的动态表达式的IQueryable Extension方法

我有以下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
}
评论
爵~maN
爵~maN

为了达成这个:

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

where the true value is depending on user input (it's not a 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);
        }

点赞
评论