Rewriting a LINQ Expression query to enable caching SQL Execution Plan

后端 未结 2 1104
攒了一身酷
攒了一身酷 2020-12-31 18:14

While reading an article on Entity Framework performance, I came across this piece of information:

Secondly, the problem [SQL Server won’t reu

2条回答
  •  时光取名叫无心
    2020-12-31 18:55

    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.

提交回复
热议问题