我正在尝试迭代字符串数组并动态创建IQueryable
查询。它很简单,但这里是我被困的地方
var query = context.QuestionsMetaDatas.AsQueryable();
var keywords=new List<string>(){ "Test1","Test2" };
foreach(var key in keywords)
{
query=query.Where(a=>a.Text.Contains(key));
}
现在的问题是,当查询生成时,其编译为
select * from QuestionsMetaDatas where Text Like "Test1" AND Text Like "Test2"
而不是AND
我希望查询生成OR
...现在我该如何实现?
答案 0 :(得分:4)
你尝试过包含其他方式吗?
var keywords=new List<int>(){ "Test1","Test2" };
query=query.Where(a=>keywords.Contains(a));
这就像IN
子句
答案 1 :(得分:4)
我使用了像Raphael建议的谓词构建器,它只是一个文件包含在你的项目中,然后你的例子就变成了:
var keywords=new List<string>(){ "Test1","Test2" };
var predicate = PredicateBuilder.False<QuestionsMetaDatas>();
foreach (var key in keywords)
{
predicate = predicate.Or (a => a.Text.Contains (key));
}
var query = context.QuestionsMetaDatas.AsQueryable().Where(predicate);
生成您正在寻找的OR查询。
答案 2 :(得分:2)
您可以查看predicate builder,或构建自己的表达式(这里是IQueryable<QuestionsMetadatas>
上带有静态扩展方法的可能解决方案)
public static IQueryable<QuestionsMetaDatas> FilterText(this IQueryable<QuestionsMetaDatas> queryable, IEnumerable<string> keywords)
{
var entityType = typeof(QuestionsMetaDatas);
var parameter = Expression.Parameter(entityType, "a");
var containsMethod = typeof(string).GetMethod("Contains"
, new[] { typeof(string) });
var propertyExpression = Expression.Property(parameter, "Text");
Expression body = Expression.Constant(false);
foreach (var keyword in keywords)
{
var innerExpression = Expression.Call(propertyExpression, containsMethod, Expression.Constant(keyword));
body = Expression.OrElse(body, innerExpression);
}
var lambda = Expression.Lambda<Func<QuestionsMetaDatas, bool>>(body, new[] { parameter });
return queryable.Where(lambda);
}
lambda
看起来像这样:
a => ((False OrElse a.Text.Contains("firstKeyWord")) OrElse a.Text.Contains("secondKeyWord"))
并且用法是
var query = context.QuestionsMetaDatas.AsQueryable();
var keywords=new List<string>(){ "Test1","Test2" };
query = query.FilterText(keywords);
或更短
var query = context.QuestionsMetaDatas.AsQueryable().FilterText(new[]{"Test1", "Test2"});