Я пытаюсь построить выражение, подобное динамически.Создайте динамическое выражение с вложенным OR между многими ANDS
SomeList.Where(person => person.firstname == "foo" &&
(person.lastanme == "bar" ||person.middleName == "bar") &&
person.age == 65)
Я использую класс под названием PredicateBuilder:
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
Я сначала проверить, если свойства объекта поиска заполняются, если они тогда я называю метод, который строит предикат, основанный на это свойство. Затем я добавляю все это в список предикатов. В конце я просматриваю и добавляю все предикаты вместе в списке с помощью метода PredicateBuilder.And().
Однако мне нужно иметь возможность отфильтровывать два разных свойства, например, от имени или от среднего имени.
Я хотел бы привести пример того, как динамически создавать эти предикаты и вставлять их или между ними, когда это необходимо, или предложение для лучшего общего дизайна для удовлетворения моих потребностей.
В приведенном ниже коде я вызываю CreatePredicate().
private static List<Expression<Func<DirectoryEntry,bool>>> _conditionsList = new List<Expression<Func<DirectoryEntry,bool>>>();
public static Expression<Func<DirectoryEntry, bool>> CreatePredicate(DirectorySearchData searchData)
{
_conditionsList.Clear();
var predicate = PredicateBuilder.False<DirectoryEntry>();
AddFirstNameCondition(searchData);
AddLastNameCondition(searchData);
AddUsernameCondition(searchData);
predicate = BuilPredicateFromConditionList(predicate);
return predicate;
}
private static void AddFirstNameCondition(DirectorySearchData searchData)
{
if (!String.IsNullOrWhiteSpace(searchData.FirstName))
{
_conditionsList.Add(entry => entry.FirstName.ToLower().Contains(searchData.FirstName.ToLower()));
}
}
private static void AddLastNameCondition(DirectorySearchData searchData)
{
if (!String.IsNullOrWhiteSpace(searchData.LastName))
{
_conditionsList.Add(entry => entry.LastName.ToLower().Contains(searchData.LastName.ToLower()));
}
}
private static void AddUsernameCondition(DirectorySearchData searchData)
{
if (!String.IsNullOrWhiteSpace(searchData.UserName))
{
_conditionsList.Add(entry => entry.Username.ToLower().Contains(searchData.UserName.ToLower()));
}
}
private static Expression<Func<DirectoryEntry, bool>> BuilPredicateFromConditionList(Expression<Func<DirectoryEntry, bool>> predicate)
{
if (_conditionsList == null || _conditionsList.Count <= 0) return predicate;
predicate = PredicateBuilder.True<DirectoryEntry>();
foreach (var condition in _conditionsList)
{
predicate = PredicateBuilder.And(predicate, condition);
}
return predicate;
}
public class DirectorySearchData
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string UserName { get; set; }
public string CampusPhone { get; set; }
public string CampusAddress { get; set; }
public string CampusBox { get; set; }
public string HomeAddress { get; set; }
public string HomeState { get; set; }
public string DepartmentOrOffice { get; set; }
public string StudentMajor { get; set; }
public string Concentration { get; set; }
public string SgaCabinetPositionName { get; set; }
public string Hiatus { get; set; }
public string StudentClass { get; set; }
public DirectorySearchData()
{
LastName = "";
FirstName = "";
UserName = "";
CampusPhone = "";
CampusAddress = "";
CampusBox = "";
HomeAddress = "";
HomeState = "";
DepartmentOrOffice = "";
StudentMajor = "";
Concentration = "";
SgaCabinetPositionName = "";
Hiatus = "";
StudentClass = "";
}
}
}
'person.firstname = "Foo" или' person.firstname = = "foo" '? Сначала исправьте свой статический код перед построением динамических выражений;) – grek40
HAHA спасибо, я просто набрал слишком быстро :) – Mike
Обратите внимание, что => это лямбда-оператор! Ваш «пример» содержит четыре (и, следовательно, не имеет смысла), но необходим только один: (p => (pa || pb) && pc) – user1890202