如何将LambdaExpression转换为类型化的Expression<Func<T, T>>?

25

我正在为nHibernate动态构建linq查询。

由于依赖关系,我希望稍后可以强制转换/检索类型化表达式,但到目前为止我一直没有成功。

以下代码不起作用(强制转换应该在其他地方发生):

var funcType = typeof (Func<,>).MakeGenericType(entityType, typeof (bool));
var typedExpression =  (Func<T, bool>)Expression.Lambda(funcType, itemPredicate, parameter); //Fails

这是有效的:

var typedExpression = Expression.Lambda<Func<T, bool>>(itemPredicate, parameter);

是否可以从LambdaExpression中获取“封装”类型的表达式?


也许你正在寻找 typedExpression.Compile()。 - Jurica Smircic
1
我需要将表达式作为IQueryable与我的ORM映射器一起使用,因此它不能被编译。 - Larantz
1个回答

33
var typedExpression =
    (Func<T, bool>)Expression.Lambda(funcType, itemPredicate, parameter); //Fails

这并不奇怪,因为你必须要 编译 一个 LambdaExpression 才能获得一个实际可调用的委托(这就是 Func<T, bool> 的作用)。
所以这段代码可以工作,但我不确定这是否符合你的需要:
// This is no longer an expression and cannot be used with IQueryable
var myDelegate =
    (Func<T, bool>)
    Expression.Lambda(funcType, itemPredicate, parameter).Compile();

如果你不是想编译表达式,而是想移动一个表达式树,那么解决方案就是将其强制转换为 Expression<Func<T, bool>>

var typedExpression = (Expression<Func<T, bool>>) 
                      Expression.Lambda(funcType, itemPredicate, parameter);

感谢您的回复。 是的,我正在寻找移动表达式树的方法。 问题在于您所提到的转换 Expression<Func<T, bool>> typedExpression = Expression.Lambda(funcType, itemPredicate, parameter); 这会导致以下错误: 无法将源类型 System.Linq.Expressions.LambdaExpression 转换为目标类型 System.Linq.Expressions.Expression<System.Func<MyType, object>> - Larantz
@Larantz:抱歉,我的错误;我忘记你需要显式转换。请查看更新后的答案。 - Jon
1
谢谢。我简直不敢相信自己竟然没有注意到缺少强制转换的Expression<>部分 :)。 - Larantz
显式转换 var typedExpression = (Expression<Func<T, bool>>) (...) 解决了我的类似问题。 - Lars Gyrup Brink Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接