I have code like this:
User rValue = null;
var userByID = new Func<User, bool>(x => x.UserId.Equals(userID, StringComparison.InvariantCultureIgnoreCase));
if (this._context.Users.Any(userByID))
{
var user = this._context.Users
.Include("nested.Associations")
.Single(userByID);
rValue = user;
}
return rValue;
I started profiling the query, and noticed that EF is NOT applying the Func<> to the SQL query, but to the collection in-mem after returning the entire .Users set.
Interestingly, the following generates the query with the correct where clause filtering the UserID:
User rValue = null;
//var userByID = new Func<User, bool>(x => x.UserId.Equals(userID, StringComparison.InvariantCultureIgnoreCase));
if (this._context.Users.Any(x => x.UserId.Equals(userID, StringComparison.InvariantCultureIgnoreCase)))
{
var user = this._context.Users
.Include("nested.Associations")
.Single(x => x.UserId.Equals(userID, StringComparison.InvariantCultureIgnoreCase));
rValue = user;
}
return rValue;
- Why will EF not build the predicate var into the generated SQL?
- Is there another way to re-use the predicate so that my code can stay clean and readable, and also have EF stuff it into the generated SQL?
EF cannot interpret compiled IL code (which your Func essentially is). It would need to guess the original code like Reflector does. That’s not an attractive design choice for a framework so it doesn’t work that way. When you inline the lambda it is not a Func. It is an expression which is analyzable. Search for “C# expression trees” to find out more.
Yes: Use
Expression<Func<User, bool>>for your variable.