在 c# 中将 WhereIf 用于多个条件

Posted

技术标签:

【中文标题】在 c# 中将 WhereIf 用于多个条件【英文标题】:Use WhereIf for multiple condition in c# 【发布时间】:2020-07-30 20:05:16 【问题描述】:

您好,有人可以帮我如何在 LINQ 中最好地使用 whereif,这里我有一个可以正常工作的代码,但我想用 WhereIf 转换这个查询。

    public async Task LoadQuery(IEnumerable<string> codes)
    
        var query = _dBContext.QueryTable.Where(x => !x.InActive).AsQueryable();

        if (codes!= null && codes.Any())
            query = query.Where(x => codes.Contains(x.FirstCode) || query.Contains(x.SecondCode));
        else
            query = query.Where(x => !x.HasException.HasValue);

        var data = query.ToList();
    

我已经用 WhereIF ienumerable 进行了尝试,但没有成功。这是我遵循的链接。 https://extensionmethod.net/csharp/ienumerable-t/whereif

【问题讨论】:

你可以试试Where(x =&gt; codes!= null &amp;&amp; codes.Any() ? (codes.Contains(x.FirstCode) || query.Contains(x.SecondCode)) : !x.HasException.HasValue),我认为 linq 可以反对,但我不确定 linq 是否可以实体。 query.Contains(x.SecondCode) 总是正确的,为什么要添加这个条件。 for whereif 在示例中,是针对linq to object(ienumerable),您应该使用Expression 而不是Func for Linq to entities(Queryable)。 【参考方案1】:

WhereIf 不太适合您的情况,原因有两个:

    您在if-else 上调用了两个不同的函数,而WhereIf 被构建为接受一个函数(predicate),如果满足某些condition 则执行。 WhereIfIEnumerable&lt;TSource&gt; 的扩展方法,而您正试图将其用作IQueryable&lt;TSource&gt; 的扩展方法。

如果您坚持,您必须为IQueryable&lt;TSource&gt; 定义一个扩展方法,并且在这样做时,只需将其定义为WhereIfElse

public static class ExtensionMethods

    public static IQueryable<TSource> WhereIfElse<TSource>(this IQueryable<TSource> source, bool condition, Func<TSource, bool> predicateIf, Func<TSource, bool> predicateElse)
    
        if (condition)
            return source.Where(predicateIf).AsQueryable();
        else
            return source.Where(predicateElse).AsQueryable();
     

所以,假设query 的类型是IQueryable&lt;Item&gt;(将Item 替换为您的实际类型):

public async Task<List<Item>> LoadQuery(IEnumerable<string> codes)

    var query = _dBContext.QueryTable.Where(x => !x.InActive).AsQueryable();
    query = query.WhereIfElse(
         // condition
         codes != null && codes.Any(),  
         // predicateIf
         (Item x) => codes.Contains(x.FirstCode) || codes.Contains(x.SecondCode), 
         // predicateElse
         (Item x) => !x.HasException.HasValue                                    
    );
    var data = query.ToList();
    return data;

附:请注意,我更改了您的返回值,但仍然没有 await

【讨论】:

【参考方案2】:
bool condition = codes!= null && codes.Any();
            var data  = _dBContext.QueryTable
                                       .WhereIf(condition, a=> codes.Contains(a.FirstCode) || codes.Contains(a.SecondCode))
                                       .WhereIf(!condition, a=> !a.HasException.HasValue && !a.InActive).ToList();

【讨论】:

以上是关于在 c# 中将 WhereIf 用于多个条件的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将多个参数化变量添加到数据库中

在 C# 中将多个 IEnumerable<T> 提要混合为一个

在 PL/SQL 存储过程中将多个变量传递给 WHERE 条件

LINQ 在 C# 中加入多个条件

如何在一个视图中将一个 UIPickerView 用于多个文本字段?

如何在 azure devops YAML 管道中将单个代理用于多个作业/阶段