我想遍历一个字符串值数组并构建一个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执行此操作,但我想使用扩展方法完成相同的操作。
答案 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
这将只留下您想要的那些相当于复合“或其中”条件的人。注意:大量被排除的项目可能会非常缓慢。