带有或者扩展方法的IQueryable

时间:2009-05-15 21:41:26

标签: c# linq iqueryable

重复:

  

How to dynamically add OR operator to WHERE clause in LINQ

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

列表中的每个项目都在一起进行“或”运算。

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” OR “B”“C”。

我知道如何使用Linq执行此操作,但我想使用扩展方法完成相同的操作。

5 个答案:

答案 0 :(得分:2)

我迟到了,但是......

我最近创建了一个关于创建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);  

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

希望这个答案仍然适合你。

答案 1 :(得分:1)

var filterValues = new[] { "A", "B", "C" };

var values =
    (from item in filterValues
     from value in searchQuery
     where value.Name.Contains(item)
     select value)
     .Distinct();

答案 2 :(得分:1)

今天我一直在努力。然后我终于意识到,如果我将数组变成一个字符串列表,我可以进行连接。一个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

答案 3 :(得分:1)

我喜欢这个解决方案:

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

在我的MVC3 WebApp上运作良好

答案 4 :(得分:0)

对于您具有已知数量的选项的情况,一种方法只是收集要排除的列表,然后应用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

这将只留下您想要的那些相当于复合“或其中”条件的人。注意:大量被排除的项目可能会非常缓慢。