While reading an article on Entity Framework performance, I came across this piece of information:
Secondly, the problem [SQL Server won’t reu
Let me recap.
You are building Expression
like this
var item = Expression.Parameter(typeof(T), "item");
var left = Expression.Property(item, idPropertyName);
Expression right = ...;
var body = Expression.Equal(left, right);
var predicate = Expression.Lambda>(body, item);
and the question is what should be used for right
in order to make EF not treating it as a constant.
Apparently primitive value like
var right = Expression.Convert(Expression.Constant(convertedId), left.Type);
doesn't work, so the solution is to provide a property of some class instance. You solved it by using anonymous type, but of course there are many other ways to do that.
For instance, using a closure (like it would have been if you were not creating the expression manually)
Expression> closure = () => convertedId;
var right = Expresion.Convert(closure.Body, left.Type);
or Tuple
instance (a bit verbose, but eliminates Expression.Convert
)
var tuple = Activator.CreateInstance(
typeof(Tuple<>).MakeGenericType(left.Type), convertedId);
var right = Expression.Property(Expression.Constant(tuple), "Item1");
etc.