Here's what I want to do :
class MyDbContext : DbContext
{
private static Expression<Func<MyClass, int>> myExpression1 = x => /* something complicated ... */;
private static Expression<Func<Item, int>> myExpression2 = x => /* something else complicated ... */;
public object GetAllData()
{
return (
from o in MyClassDbSet.AsExpandable()
select new
{
data1 = myExpression1.Invoke(o), // problem 1
data2 = o.Items.Select(myExpression2.Compile()) // problem 2
}
);
}
}
UPDATE :
myExpression
has to stay separated from my query, because I want to reuse it in multiple LINQ queries.
UPDATE 2 :
Separated myExpression
into myExpression1
and myExpression2
to make clear the fact that I want to reuse them separately.
UPDATE 3 :
Added LINQkit to example.
Problem 1 throws : Unable to cast an object of type 'System.Linq.Expressions.FieldExpression' to type 'System.Linq.Expressions.LambdaExpression'.
Problem 2 throws : Internal .NET Framework Data Provider error 1025.
On the first problem when using LinqKit you need to assign your expression to a local variable before .Invoke()ing it. More complete explanation can be found on this question.
The second problem is that the select method accept a object of type:
Expression<Func<TSource, TResult>>
Which means that you must supply a lambda expression accepting a TSource object as a parameter and returning a TResult object.
Your TSource object is Item, that is the table you are making your query from. Your TResult is a int in your example, that is what you defined on the expression.
So you must call .Invoke() on the second expression passing a Item object as a parameter, in the same way that you passed the MyClassDbSet object "o". Actually, there is only syntactical diference on both select statements, they essentialy do the same thing.
And you should not call .Compile() on the expressions, this produces a:
Func<TSource, TResult>
Which is a delegate to the compiled version of the expression tree and cannot be translated into a SQL expression. More information can be found here.
It should work with the following changes:
class MyDbContext : DbContext
{
private static Expression<Func<MyClass, int>> myExpression1 = x => /* something complicated ... */;
private static Expression<Func<Item, int>> myExpression2 = x => /* something else complicated ... */;
public object GetAllData()
{
Expression<Func<MyClass, int>> myLocalExpression1 = myExpression1;
Expression<Func<MyClass, int>> myLocalExpression2 = myExpression2;
return (
from o in MyClassDbSet.AsExpandable()
select new
{
data1 = myLocalExpression1.Invoke(o),
data2 = o.Items.Select(item => myLocalExpression1.Invoke(item))
}
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With