数组属性筛选器的动态lambda表达式

本文关键字:动态 lambda 表达式 属性 筛选 数组 | 更新日期: 2023-09-27 18:25:48

根据需要,我想使用C#创建一个动态lambda表达式。

例如,我想生成像这样的动态查询

Employee. Address[1].City

我该怎么做?请注意,该属性是动态的。

我试过这个代码

var item = Expression.Parameter(typeof(Employee), "item");
Expression prop = Expression.Property(item, "Address", new Expression[] { Expression.Constant[1] });
prop = Expression.Property(prop, "City");
var propValue = Expression.Constant(constraintItem.State);
var expression = Expression.Equal(prop, propValue);
var lambda = Expression.Lambda<Func<Line, bool>>(expression, item);

但这并没有奏效。

如有任何帮助,我们将不胜感激。

谢谢。

数组属性筛选器的动态lambda表达式

您的"动态查询"表达式(实际上不是查询,它是一个简单的MemberExpression)可以生成如下:

ParameterExpression param = Expression.Parameter(typeof(Employee), "item");
MemberExpression address = Expression.Property(param, "Address");
BinaryExpression indexedAddress = Expression.ArrayIndex(address, Expression.Constant(1));
MemberExpression city = Expression.Property(indexedAddress, "City"); // Assuming "City" is a string.
// This will give us: item => item.Address[1].City
Expression<Func<Employee, string>> memberAccessLambda = Expression.Lambda<Func<Employee, string>>(city, param);

如果您希望使用一个实际的谓词作为查询的一部分,只需使用相关的比较表达式(即)包装MemberExpression

BinaryExpression eq = Expression.Equal(city, Expression.Constant("New York"));
// This will give us: item => item.Address[1].City == "New York"
Expression<Func<Employee, bool>> predicateLambda = Expression.Lambda<Func<Employee, bool>>(eq, param);

就代码而言:不确定为什么要创建一个委托类型为Func<Line, bool>的lambda,而输入显然应该是Employee。参数类型必须始终与委托签名匹配。

编辑

非数组索引器访问示例:

ParameterExpression param = Expression.Parameter(typeof(Employee), "item");
MemberExpression address = Expression.Property(param, "Address");
IndexExpression indexedAddress = Expression.MakeIndex(
    address,
    indexer: typeof(List<string>).GetProperty("Item", returnType: typeof(string), types: new[] { typeof(int) }),
    arguments: new[] { Expression.Constant(1) }
);
// Produces item => item.Address[1].
Expression<Func<Employee, string>> lambda = Expression.Lambda<Func<Employee, string>>(indexedAddress, param);
// Predicate (item => item.Address[1] == "Place"):
BinaryExpression eq = Expression.Equal(indexedAddress, Expression.Constant("Place"));
Expression<Func<Employee, bool>> predicateLambda = Expression.Lambda<Func<Employee, bool>>(eq, param);