1
votes

I am doing a query using linq to entities and I want to reuse the same code but with a slightly different select statement. This is the query:

return from f in GetFields<T>()
     where f.Id == Id
     select new Prop<V>
         {
           Name = f.Name,
           Value = toValue(f.value)
         };

where toValue is a Func that creates a new Value object. I want to use several toValue function which have this kind of body:

var toValue = f => new DerivedValueClass {
                 FirstField = f.FirstField,
                 SecondField = f.SecondField
              }

So it is just simple assignment, which will be easily translated by sql to entities. However when I execute the code, linq to entities states:

The LINQ expression node type 'Invoke' is not supported in LINQ to Entities

I guess it is not possible to call the toValue function, since it can't be translated. How can I create an expression from the function toValue in order to use it inside the linq query?

1

1 Answers

0
votes

Eventually I find out that Linqkit allows to do this kind of things very easily:

Expression<Func<T, V>> toValue =  a => new DerivedObject() { 
    // perform assignment here
}

return from f in GetFields<T>().AsExpandable() // <- LinqKit AsExpandable() extension method
 where f.Id == Id
 select new Prop<V>
     {
       Name = f.Name,
       Value = toValue.Invoke(f.value) // <- LinqKit Invoke() extension method
     };

It is really important that toValue is an Expression, since the compiler will create an ExpressionTree instead of simply generating a lambda expression. Linqkit use some trick in order to replace the toValue invocation with an expression tree. More info on the LinqKit site and here