简体   繁体   English

自定义 LINQ Where 子句实际上不适用 Where

[英]Custom LINQ Where clause not actually applying Where

I have a custom Filter Expression where a user can send a dictionary to my api and I will create a custom where clause.我有一个自定义过滤器表达式,用户可以将字典发送到我的 api,我将创建一个自定义 where 子句。 I am no expert in writing custom LINQ so if there is a better way then that would be great as well.我不是编写自定义 LINQ 的专家,所以如果有更好的方法,那也很好。

All of this works (No errors) but it doesn't apply my filtering thus returning all it can find)所有这些都有效(没有错误),但它不应用我的过滤,因此返回它可以找到的所有内容)

My Repository call where I append my custom filter (Look at the "FilterByString" area).我的存储库调用 append 我的自定义过滤器(查看“FilterByString”区域)。 _entities is a DbSet _entities 是一个 DbSet

// This is in my contructor
private readonly DbSet<T2> _entities;
_entities = _context.Set<T2>();

public async Task<BasePagedResponse<T1>> PagedList(Guid companyId, int pageNumber, int pageSize, Dictionary<string, string> filterParameters, Expression<Func<T2, bool>> predicate, Func<IQueryable<T2>, IIncludableQueryable<T2, object>> including = null)
    {
        try
        {
            var modelList = await _entities
                                    .AsQueryable()
                                    .Where(predicate)
                                    .CustomInclude(including)
                                    .FilterByString(filterParameters)
                                    .Skip((pageNumber - 1) * pageSize)
                                    .Take(pageSize).ToListAsync();

            var mappedList = _mapper.Map<List<T1>>(modelList);
            var total = await GetTotalRecords(companyId);
            var pagedResult = new PagedResult<T1>(mappedList, total, pageNumber, pageSize);
            
            return new BasePagedResponse<T1>(pagedResult, true, null);
        }
        catch (SqlException ex)
        {
            return new BasePagedResponse<T1>(null, false, new[] { new Error(GlobalVariables.error_list, $"Error listing models-({typeof(T1).Name}). {ex.Message}") });
        }
    }

My static SQL Helper that takes the source query and appends my custom Where Clause我的 static SQL 帮助程序接受源查询并附加我的自定义 Where 子句

 public static IQueryable<T> FilterByString<T>(this IQueryable<T> source, Dictionary<string, string> filterParameters = null)
    {
        if (filterParameters != null)
        {
            foreach (var keyValuePair in filterParameters)
            {
                source.Where(Filter<T>(keyValuePair.Key, keyValuePair.Value));
            }
        }

        return source;
    }

My custom "Filter" (Looks like a lot but it just looks for types of string, bool or int to filter on)我的自定义“过滤器”(看起来很多,但它只是寻找要过滤的字符串、布尔或整数类型)

private static Expression<Func<T, bool>> Filter<T>(string propertyName, string queryText)
    {
        var parameter = Expression.Parameter(typeof(T), "entity");
        var getter = Expression.Property(parameter, propertyName);
        if (getter.Type == typeof(string))
        {
            var stringContainsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            var containsCall = Expression.Call(getter, stringContainsMethod,
                Expression.Constant(queryText, typeof(string)));
            return Expression.Lambda<Func<T, bool>>(containsCall, parameter);
        }
        if (getter.Type == typeof(int))
        {
            var stringEqualsMethod = typeof(int).GetMethod("Equals", new[] { typeof(int) });
            var equalsCall = Expression.Call(getter, stringEqualsMethod,
                Expression.Constant(value: Int32.Parse(queryText), typeof(Int32)));
            return Expression.Lambda<Func<T, bool>>(equalsCall, parameter);
        }
        if (getter.Type == typeof(bool))
        {
            var stringEqualsMethod = typeof(bool).GetMethod("Equals", new[] { typeof(bool) });
            var equalsCall = Expression.Call(getter, stringEqualsMethod,
                Expression.Constant(value: bool.Parse(queryText), typeof(bool)));
            return Expression.Lambda<Func<T, bool>>(equalsCall, parameter);
        }

        throw new Exception("No proper type defined for Filter Parameter. Supports only String, Int and Boolean");
    }

It is a decorator API, where .Where(...) returns a query that is composed to include the predicate, but which does not change the original query;它是一个装饰器API,其中.Where(...)返回一个包含谓词的查询,但不会更改原始查询; you need to retain the result:你需要保留结果:

foreach (var keyValuePair in filterParameters)
{
    source = source.Where(Filter<T>(keyValuePair.Key, keyValuePair.Value));
    // ^^^^^
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM