我有用于数据过滤的表达式树代码,直到日期它在通用列表List<T>
上使用并且代码使用后工作正常:
var parameterType = Expression.Parameter(typeof(T), "obj");
var memberExpression = Expression.Property(parameterType, "Name");
按如下方式创建二进制表达式并处理结果很容易:
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));
此处Name
是Type T
中的属性,因为Lambda编译后的结果是Func<T,bool>
,我用它来将Where
条款应用于IEnumerable
}类型。现在底层系统已更改为在Dictionary<string,T>
上使用相同的代码,因此集合中的所有Type T值现在都有一个字符串Key关联,类型T现在可以作为字典对象的值访问。此外,我正在申请一个IQueryable
,它采用一个表达式树,源头的最终lambda后期编译将是Func<KeyValuePair<string,T>,bool>
,因此无法在最终结果处理中应用该值。
以下是现在的代码修改:
var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");
以下代码失败,因为现在Name属性位于KeyValuePair的Value中,我们无法将其用作Type T:
var memberExpression = Expression.Property(parameterType, "Name");
任何指向它的指针或任何建议让我朝着正确的方向前进?
答案 0 :(得分:1)
你可以通过这种方式调用[“name”]项来获得Expression:
var nameProperty= Expression.Call(parameterType,
typeof(IDictionary<string, T>).GetMethod("get_Item"),
Expression.Constant("Name"));
或作为:
var nameProperty = Expression.Property(parameterType, "Item",
new Expression[] { Expression.Constant("Name") });
两者都是Item
属性
编辑:要从KeyValuePair
获取价值,您必须获取属性密钥,将其与“名称”和属性值进行比较,并将其与值进行比较:
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);