根据要求,我想使用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);
但它不起作用。
任何帮助将不胜感激。
感谢。
答案 0 :(得分:2)
您的“动态查询”表达式(实际上不是查询,它是一个简单的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>
时,不确定为什么要创建一个委托类型为Employee
的lambda。参数类型必须始终与委托签名匹配。
修改强>
非数组索引器访问示例:
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);