Самое простое - использовать 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;
Я пропустил проверки на равенство, потому что "Contains" (т.е. 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);