我遇到了麻烦,想不出来似乎是一件非常简单的事情,在普通的SQL中可以在1分钟内完成,到目前为止已经有几个小时了。情况如下:
根据我想要完成的内容,返回类型是强制性的:
public Expression<Func<MyEntity, bool>> GetSearchExpression(string text)
{
Expression<Func<MyEntity, bool>> result;
var keywords = text.Trim().Split(" ");
foreach(var keyword in keywords)
{
// TODO:
// check whether 'OR' is required (i.e. after second loop)
// (firstname = 'keyword'
// AND
// middlename = 'keyword'
// AND
// lastname = 'keyword')
// OR
// (firstname like '%keyword%'
// AND
// middlename like '%keyword%'
// AND
// lastname like '%keyword%')
}
return result;
}
提前致谢!
答案 0 :(得分:1)
最简单的方法是使用Joe Albahari的PredicateBuilder来做这样的事情:
var predicate = PredicateBuilder.False<MyEntity>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (
p => p.FirstName.Contains (temp) &&
p.LastName.Contains (temp) &&
p.MiddleName.Contains (temp));
}
return predicate;
我省略了平等检查,因为“包含”(即like '%...%'
)无论如何都会涵盖这种可能性。
var predicate = PredicateBuilder.True<MyEntity>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.And (
p => p.FirstName.Contains (temp) ||
p.LastName.Contains (temp) ||
p.MiddleName.Contains (temp));
}
return predicate;
最后一点:由于PredicateBuilder要求您在创建查询时致电.AsExpandable()
,我不知道这是否适合您。您可能不得不求助于构建自己的表达式,这可能有点单调乏味。不过,这可以让你开始:
var pParam = Expression.Parameter(typeof(MyEntity), "p");
var predicate = Expression.Constant(true);
foreach (string keyword in keywords)
{
var keywordExpr = Expression.Constant(keyword);
// TODO: create an expression to invoke .FirstName getter
// TODO: create an expression to invoke string.Contains() method
//TODO: do the same for lastname and middlename
predicate = Expression.And(predicate,
Expression.Or(
Expression.Or(firstNameContainsKeyword,
middleNameContainsKeyword),
lastNameContainsKeyword));
}
return Expression.Lambda<Func<MyEntity, bool>>(predicate, pParam);