使用System.Linq.Expressions API重写Lambda表达式

时间:2015-04-11 08:01:32

标签: c# linq expression

我被困在这几个小时。我想做的就是通过使用Expression class APIs重写下面的表达式来构建表达式树:

var Expression<Func<T, bool>> expr = x => x.SomeProperty == value;

到目前为止我得到的是:

{
     var param = Expression.Parameter(typeof(T), "x");
     var lhs = Expression.Property(param, "SomeProperty");
     var rhs = Expression.Constant(value, value.GetType());
     return Expression.Call(typeof(object).GetMethod("Equals", BindingFlags.Static | BindingFlags.Public), lhs, rhs);
}

如果T是基本类型或枚举,则此方法可以正常工作。但是如果T是引用类型,class等等,我得到了一个例外。

异常消息:

  

无法创建“TypeName”类型的常量值。只有原始   在此上下文中支持类型或枚举类型。

提前致谢。

2 个答案:

答案 0 :(得分:1)

在这种情况下,您不需要显式指定类型,只要该值不为null(我假设它不是,因为您在其上调用GetType()

这应该这样做。

var param = Expression.Parameter(typeof(T), "x");
var property = Expression.Property(param, "SomeProperty");
var compareValue = Expression.Constant(value);
var equals = Expression.Equal(property, compareValue);
return Expression.Lambda<Func<T, bool>>(equals, param);

答案 1 :(得分:0)

生成的表达式传递给Linq Where调用。像这样。

 Context.Sources.Where(criteria.BuildQuery());

在评估/翻译表达式时抛出异常。

如果我编译表达式然后将委托传递给Where调用,那么一切都按预期工作。

 Context.Sources.Where(criteria.BuildQuery().Compile());

我不确定它有什么不同,如果有人知道为什么请开导我们。