5

复制:

如何在 LINQ 中将 OR 运算符动态添加到 WHERE 子句

我想遍历一个字符串值数组并构建一个 linq 表达式

列表中的每个项目都是 OR'ed 在一起的。

string[] search = new string[]{"A", "B", "C"};
foreach (string item in filterValues)
{
    searchQuery = searchQuery.Where(s => s.Name.Contains(item));
}

上面的代码搜索“A” AND “B” AND “C”

我想搜索“A”“B”“C”。

我知道如何使用 Linq 做到这一点,但我想使用扩展方法来完成同样的事情。

4

5 回答 5

1

我参加聚会迟到了,但是...

我最近创建了一个关于创建启用以下语法的 IQueryable 搜索扩展方法的博客:

string[] search = new string[]{"A", "B", "C"};
var searchQuery = context.Users.Search(u => u.Name, search); 

更新:开始

此后,我更新了搜索扩展,这影响了使用新的流畅 API 执行搜索的方式。这意味着上面现在应该写成

var searchQuery = context.Users.Search(u => u.Name)
                               .Containing("A", "B", "C"); 

有关新 api 的更多信息,请参见此处:http: //jnye.co/Posts/2030/searchextensions-search-strings-with-the-new-fluent-api

更新:完

http://jnye.co/Posts/8/generic-iqueryable-or-search-for-multiple-search-terms-using-expression-trees

https://github.com/ninjanye/SearchExtensions

我还有一个可以从这里安装的 nuget 包:

http://www.nuget.org/packages/NinjaNye.SearchExtensions/

但是,如果您想自己执行此操作,则需要执行以下操作:首先,您需要创建扩展方法

public static class QueryableExtensions  
{  
    public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, params string[] searchTerms)  
    {  
        if (!searchTerms.Any())  
        {  
            return source;  
        }  
  
        Expression orExpression = null;  
        foreach (var searchTerm in searchTerms)  
        {  
            //Create expression to represent x.[property].Contains(searchTerm)  
            var searchTermExpression = Expression.Constant(searchTerm);  
            var containsExpression = BuildContainsExpression(stringProperty, searchTermExpression);  
  
            orExpression = BuildOrExpression(orExpression, containsExpression);  
        }  
  
        var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, stringProperty.Parameters);  
        return source.Where(completeExpression);  
    }  
  
    private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)  
    {  
        if (existingExpression == null)  
        {  
            return expressionToAdd;  
        }  
  
        //Build 'OR' expression for each property  
        return Expression.OrElse(existingExpression, expressionToAdd);  
    }  
}

然后可以按如下方式使用:

string[] search = new string[]{"A", "B", "C"};
var searchQuery = context.Users.Search(u => u.Name, search);  

这将创建您所追求的 or 查询。

希望这个答案仍然与您相关。

于 2013-07-05T10:02:32.127 回答
0

我今天为此苦苦挣扎。然后我终于意识到,如果我将数组变成一个字符串列表,我可以进行连接。一个 queryextender 控件 (.NET 4) 正在调用下面的函数。不要忘记订单...这很重要。如果你不使用它,你会得到一个错误。

    Protected Sub FilterTestType(ByVal sender As Object, ByVal e As CustomExpressionEventArgs)
    Dim _codes As List(Of String) = GetTestCodes()
    e.Query = From _tests In e.Query.Cast(Of LabTest)()
              Join _code In _codes On _tests.TestCode Equals _code
              Order By _tests.LoadDate Descending
              Select _tests
End Sub
于 2010-06-16T21:44:52.550 回答
0
var filterValues = new[] { "A", "B", "C" };

var values =
    (from item in filterValues
     from value in searchQuery
     where value.Name.Contains(item)
     select value)
     .Distinct();
于 2009-08-03T03:23:48.977 回答
0

对于已知数量的 where 选择的情况,一种方法是简单地收集要排除的列表,然后应用 where 方法。

dim BASEQUERY = FROM blah in blahblahblah _
WHERE ....
select blah

For Each item In EXCLUDELIST
Dim sitem As String = item
BASEQUERY = BASEQUERY.Where(Function(py) py.YOURCOLUMN <> sitem)
Next

这将只留下您想要的那些相当于复合“或位置”条件的内容。注意:大量排除的项目可能会异常缓慢。

于 2014-10-21T18:27:33.940 回答
0

我喜欢这个解决方案:

string[] search = new string[]{"A", "B", "C"};
foreach (string item in filterValues)
{
    searchQuery = searchQuery.Where(s => s.Name.Contains(item)).Concat(searchQuery);
}

在我的 MVC3 WebApp 上运行良好

于 2012-03-02T15:45:11.327 回答