如何告诉 LINQ 如果条件为 false 则跳过 where?

Pop*_*Pop -5 c# linq .net-4.0

参考下面的代码:

而不是有这么多 if else 语句:

List<T> GetTs(string createBy, bool isAdmin, string departmentCode, ...)
{
    if(isAdmin)
    {
        if(!string.IsNullOrEmpty(createBy))
        {
            var query = context.table
                        .Where(x => string.compare(x.createBy, createBy, StringComparison.OrdinalIgnoreCase) == 0)
                        .ToList();
            return query;
        }
        else
        {
            var query = context.table.ToList();
            return query;
        }
    }
    else
    {
        if(!string.IsNullOrEmpty(createBy))
        {
            var query = context.table
                        .Where(x => string.compare(x.departmentCode, departmentCode, StringComparison.OrdinalIgnoreCase) == 0)
                        .Where(x => string.compare(x.createBy, createBy, StringComparison.OrdinalIgnoreCase) == 0)
                        .ToList();
            return query;
        }
        else
        {
            var query = context.table
                        .Where(x => string.compare(x.departmentCode, departmentCode, StringComparison.OrdinalIgnoreCase) == 0)
                        .ToList();
            return query;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以在没有那么多 if else 语句的情况下这样做吗:

var query  = context.table
                .Where(x => (!isAdmin)? string.compare(x.departmentCode, departmentCode, StringComparison.OrdinalIgnoreCase) == 0) : SKIP THIS '.Where')
                .Where(x => (!string.IsNullOrEmpty(createBy))? string.compare(x.createBy, createBy, StringComparison.OrdinalIgnoreCase) == 0) : SKIP THIS '.Where')
                //...
                .ToList();
Run Code Online (Sandbox Code Playgroud)

如何告诉 LINQ 跳过.Whereif 条件为 false?可能的?

以下评论中帕特里克·霍夫曼的建议有效:

var query  = context.table
                .Where(x => (!isAdmin)? string.compare(x.departmentCode, departmentCode, StringComparison.OrdinalIgnoreCase) == 0) : true)
                .Where(x => (!string.IsNullOrEmpty(createBy))? string.compare(x.createBy, createBy, StringComparison.OrdinalIgnoreCase) == 0) : true)
                //...
                .ToList();
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 5

如果我理解意图(有条件地应用谓词),那么基本上:以不同的方式进行组合:

IQueryable<Whatever> query = context.Table;
if(condition1)
    query = query.Where(x => x.column1);
if(condition2)
    query = query.Where(x => x.column2);
//...etc
var list = query.ToList();
Run Code Online (Sandbox Code Playgroud)

您可能可以将其包装在扩展方法中,例如

static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition,
        Expression<Func<T,bool>> predicate)
    => condition ? query.Where(predicate) : query;
Run Code Online (Sandbox Code Playgroud)

和:

var list= context.Table.WhereIf(condition1, x => x.column1)
                       .WhereIf(condition2, x => x.column2)
                       // ...
                       .ToList();
Run Code Online (Sandbox Code Playgroud)

但是,我可能不会这样做,因为在许多情况下,它需要构建不必要的附加表达式树。

  • 我不确定这是否回答了问题。我什至认为我不明白这个问题。 (4认同)