简体   繁体   中英

Rewrite Lambda expression with System.Linq.Expressions APIs

I am stuck on this for hours. All I want to do is build an Expression tree by rewriting this following expression using Expression class APIs :

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

What I got so far are:

{
     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);
}

This works fine if T is a primitive type or enumeration. But I got an exception if T is a reference type, a class etc.

Exception Message:

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

Thanks in advance.

You don't need to specify the type explicitly, in this case, as long as the value is not null (which I'm assuming it isn't, as you're calling GetType() on it).

This should do it.

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);

The expression generated was passed to a Linq Where call. Like this.

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

The exception was thrown when the expression is being evaluated/translated.

If I compile the expression and then pass a delegate to the Where call, everything works as expected.

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

I am not sure what difference it makes, if someone knows why please enlighten us.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM