我想建立一個像動態下面的表達式。建立一個動態表達式與嵌套或之間的許多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 = 「富」'或'person.firstname = =「foo」'?首先在構建動態表達式之前糾正你的靜態代碼;) – grek40
HAHA謝謝,我只是打字太快:) – Mike
請注意=>是lambda操作符!您的「示例」包含四個(因此沒有意義),但只有一個是必要的,如下所示: (p =>(pa || pb)&& pc) – user1890202