我可以使用LINQ表达式参数化PropertyExpression的属性名称吗?

时间:2012-01-11 17:14:19

标签: .net linq reflection expression

假设我有以下LambdaExpression:

var itemParam = Expression.Parameter(typeof(Thing), "thing");
var someValue = "ABCXYZ123"; // value to compare

LambdaExpression lex = Expression.Lambda(
  Expression.Equal(
    Expression.Property(itemParam, "Id"), // I want ID to be a Body expression parameter
    Expression.Constant(someValue)
  ), itemParm);

我希望Expression.Property(...)工厂中的属性名称(第二个参数)是一个参数,我该怎么做呢?

我希望看到一个看起来像这样的构造函数,但它不存在:

Expresssion.Property(Expression instance, Expression propName)

是否有一些技巧可以将参数化的ConstantExpression转换为所需的字符串或MemberInfo?也许我的方式错了。

我的预感是,因为这些表达式树在编译时变为轻量级IL,所以需要成员访问信息,因此,在构造表达式树时必须提供成员和属性的名称。

感谢您的任何提示!

编辑:想要补充一点,这将用作Enumerable.Where(...)扩展方法的参数,用于确定两个类/实体之间关系的匹配。

1 个答案:

答案 0 :(得分:2)

表达式树表示与您在C#/ VB.NET程序中看到的大致的IL结构。您无法参数化该属性表达式,原因与您无法“参数化”以下代码的原因相同:

var x = new MyClass {Id = 1, Name = "hello"};
var propName = "Id";
var xId = x.propName; // <-- This will not compile

如果需要实现此功能,并且表达式树未传递给IQueryable<T>,则可以编写一个带有对象和字符串的辅助函数,并返回该字符串标识的该对象属性的值;然后,您可以使用Expression.Call将该辅助函数调用到您正在构建的表达式树中。