我正在使用Linq To Entities来启动我的应用程序,我想创建一个非常复杂的搜索查询...看看我想要的是:
当用户输入像“华盛顿波士顿”这样的字符串时,我将根据“”(空格,在这种情况下为2个字符串)的数量打破N个字符串并在我的Counties表中搜索华盛顿和波士顿< / p>
如果这是一个“静态”查询,我会这样写:where county.Name.Contains("Washington") || county.Name.Contains("Boston")
但我不知道用户将输入多少个城市(或白色空间)...
在经典的纯TSQL环境中,我会在运行时编译查询并使用命令Exec ...所以我的问题是:如何动态生成LINQ to实体查询?
请注意.Where()不是基于委托的扩展方法...它不会在后端转换为TSQL,这意味着from e in context.Counties.Where(c => c.Name.Contains("boston"))
会转换为后端的SELECT ID,NAME FROM COUNTIES
答案 0 :(得分:5)
我只是将David Khaykin的评论扩展为答案,因为这是达到要求的最简单方法。
您只需将搜索字词拆分为字词列表,然后根据您的要求使用counties
方法过滤Contains
实体
var terms = searchTerm.Split(' ').ToList();
// an exact match
counties.Where(c => terms.Contains(c.Name))
// a 'contains' or 'like' type match
counties.Where(c => terms.Any(t => c.Contains(t));
Contains
方法是System.Linq.Enumerable.Contains,而不是String.Contains
。
在编写任何复杂的动态LINQ查询时,您可以使用bmused概述的方法 - 非常强大。但是对于这种类型的简单过滤,您可以传递直接列表。
答案 1 :(得分:2)
所以你会做类似的事情(未经测试):
public Expression<Func<County, Boolean>> GetPredicate(List<String> terms)
{
//The string method - Contains
MethodInfo mContains = typeof(String).GetMethod("Contains");
//The parameter - county
ParameterExpression pe = Expression.Parameter(typeof(County), "County");
//The property - Name
Expression property = Expression.Property(pe, "Name");
//expression body
Expression body = null;
foreach(String term in terms)
{
//the constant to look for
Expression searchTerm = Expression.Constant(term);
//build expression body
if(body == null) body = Expression.Call(property, mContains, searchTerm);
else body = Expression.OrElse(body,
Expression.Call(property, mContains, searchTerm));
}
//create predicate
return Expression.Lambda<Func<County, Boolean>>(body, pe);
}
答案 2 :(得分:2)
您可以使用Predicate builder(和LINQKit,因为您正在使用实体框架),这样您就可以执行此操作:
IQueryable<County> SearchInCountyNames(params string[] countyNames)
{
var predicate = PredicateBuilder.False<County>();
foreach (string countyName in countyNames)
{
string name = countyName;
predicate = predicate.Or(c => c.Name.Contains(name));
}
return dataContext.Counties.AsExpandable().Where(predicate);
}
谓词构建器站点上有更多示例。