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

Rewrite Lambda expression with System.Linq.Expressions APIs

我坚持了几个小时。我想要做的就是通过使用 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

异常消息:

Unable to create a constant value of type 'TypeName'. Only primitive types or enumeration types are supported in this context.

提前致谢。

你不需要明确指定类型,在这种情况下,只要值不为空(我假设它不是,因为你调用 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);

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

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

表达式被evaluated/translated时抛出异常。

如果我编译表达式,然后将委托传递给 Where 调用,一切都会按预期进行。

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

不知道有什么区别,有知道的请赐教。