When I write expressions in our application as lambda expressions, I can usually make use of the following construct1:
dbContext.Contents<MyEntity>()
(dbContext is of a custom class.)
Somehow, Linq1Entities/Entity Framework understands this to mean I am SELECTing items from the table matching MyEntity.
Now, I am constructing an expression by means of the System.Linq.Expressions classes.
I have tried to replicate the above fragment like so:
Expression.Call(Expression.Constant(dbContext), contentsMethod)
contentsMethod has been initialized to the appropriate MethodInfo before by means of reflection.
Unfortunately, this does not work.
Entity Framework complains that it cannot convert the dbContext object to SQL.
I have built an analogous expression of what I wanted as a lambda expression and looked at the resulting expression tree in the debugger.
Interestingly, instead of a constant, the dbContext was modeled as a member access of what seemed to be a closure object.
Why is that? Why is a local variable dbContext represented by a member access to the closure in an expression, and why doesn't it alternatively work as a constant value? Does it matter that dbContext was a parameter of the enclosing method in my case?
My question is not how to solve the issue. I already did, by introducing the fragment shown above as an extra lambda expression whose body gets tied into my manually built expression.
1: An example of how that fragment is used is the following expression:
dbContext.Contents<MyEntity1>().Where(e1 => dbContext.Contents<MyEntity2>().Any(e2 => e1.Name == e2.Key))
dbContext.Contents<MyEntity>()? As is question seems very unclear, at least for me. I understand that you have dbContext parameter, you pass it to some lambda, it got captured and it's access becomes member-access of closure object.Expression.Constant(dbContext)(to be exact -Expression.PropertyOrField(Expression.Constant(dbContext), "NameOfMyDbSetProperty"))), representing your exactAnyquery, and it works fine without complaining from EF side.Set<T>)