我想創建動態拉姆達表達式,以便我可以使用一組過濾參數來過濾列表。這是我到目前爲止有:動態遞歸拉姆達表達式
的表達式使用內置的方法波紋管,其中T是列表的對象類型
public static Expression<Func<T, bool>> GetExpression<T>(IList<DynamicFilter> filters)
{
if (filters.Count == 0)
return null;
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = null;
if (filters.Count == 1)
exp = GetExpression<T>(param, filters[0]);
[...]
return Expression.Lambda<Func<T, bool>>(exp, param);
}
private static Expression GetExpression<T>(ParameterExpression param, DynamicFilter filter)
{
MemberExpression member = Expression.Property(param, filter.PropertyName);
ConstantExpression constant = Expression.Constant(filter.Value);
[...]
return Expression.Call(member, filterMethod, constant);
}
我再打電話
List<Example> list = ...;
var deleg = ExpressionBuilder.GetExpression<Example>(dynFiltersList).Compile();
list = list.Where(deleg).ToList();
這個工程只是正如所期望的那樣,只包含簡單類型的對象,但如果內部存在複雜類型,代碼將不再工作。例如,假設我在Example類中有一個自定義類型Field的成員,並且Field有一個字符串屬性Value。如果filter.PropertyName
是'Field0'(字段類型),代碼將工作得很好,但如果我有'Field0.Value',我會得到一個明顯的錯誤,指出在類Example中沒有名爲'Field0.Value'的屬性。
我試圖修改表達構建方法,像這樣:
MemberExpression member = null;
if (filter.PropertyName.Contains('.'))
{
string[] props = filter.PropertyName.Split('.');
ParameterExpression param1 = Expression.Parameter(typeof(T).GetProperty(props[0]).PropertyType, "t1");
member = Expression.Property(param1, props[0]);
}
else
{
member = Expression.Property(param, filter.PropertyName);
}
但後來我在編譯時表達了一個Lambda parameter not in scope
錯誤。我有點理解爲什麼我得到這個錯誤,但我不知道如何使這項工作。
底線是我需要使表達式構建方法在形成MemberExpression時遞歸地工作。我最終需要獲得一個list = list.Where(deleg).ToList();
,這意味着像這樣的list = list.Where(obj => obj.Field0.Value == 'something').ToList();
我剛開始使用表達式,所以我真的不知道在這方面太多,但任何幫助將不勝感激。
感謝
它看起來可以工作,但我現在無法測試它。無論如何,我使用Microsoft提供的動態linq庫解決了我的問題,如下所示:[在Linq-to-Entities中編寫動態Linq查詢](http://naspinski.net/post/Writing-Dynamic-Linq-Queries-in- Linq-to-Entities.aspx)與自定義表達式構建器相結合。 – 2011-10-25 06:11:25
一個很好的解決方案!第一次實施並運行。 – paqogomez 2014-02-10 20:37:30