I have expression tree code used for data filtering, till date it was used on a Generic list List<T>
and following code use to work fine:
var parameterType = Expression.Parameter(typeof(T), "obj");
var memberExpression = Expression.Property(parameterType, "Name");
It was easy to create a binary expression as follows and process the result:
var constantExpression = Expression.Constant("Jack",typeof(string));
var finalExpression = Expression.Equal(memberExpression,constantExpression);
var resultFunc = Expression.Lambda<Func<T, bool>>(finalExpression, parameterType).Compile();
// Final Result
sourceList.Where(obj => resultFunc(obj));
Here Name
is a property in Type T
, as result post Lambda compilation was Func<T,bool>
, I use to apply the same to the Where
clause of IEnumerable
type. Now the underlying system has changed to use the same code on Dictionary<string,T>
, so all the Type T values in the collection now have a string Key associated and type T is now accessible as a value of dictionary object. Also I am applying on a IQueryable
, which takes an expression tree the final lambda post compilation at source would be Func<KeyValuePair<string,T>,bool>
, therefore cannot apply the Value in the final result processing.
Following is the code modification now:
var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");
Following code fails, since now Name property is in Value of the KeyValuePair and we cannot use it as Type T:
var memberExpression = Expression.Property(parameterType, "Name");
Any pointer to make it work or any suggestion to set me in the right direction?
You could get Expression for calling ["name"] item this way:
var nameProperty= Expression.Call(parameterType,
typeof(IDictionary<string, T>).GetMethod("get_Item"),
Expression.Constant("Name"));
or as:
var nameProperty = Expression.Property(parameterType, "Item",
new Expression[] { Expression.Constant("Name") });
Both is call of Item
property
EDIT : To get Value from KeyValuePair
you have to get property Key, compare it with "Name" and a property Value and compare it with value:
var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");
var value = Expression.Property(parameterType, "Value" );
var key = Expression.Property(parameterType, "Key");
var eq1 = Expression.Equal(key, Expression.Constant("Name"));
var eq2 = Expression.Equal(value, constantExpression);
var and = Expression.And(eq1, eq2);
var lambda = Expression.Lambda(and, parameterType);