2

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;
  1. Why will EF not build the predicate var into the generated SQL?
  2. 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?

1 Answer 1

4
  1. 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.

  2. Yes: Use Expression<Func<User, bool>> for your variable.

Sign up to request clarification or add additional context in comments.

3 Comments

Interesting. That makes sense, though it isn't obvious that would be the case. Trying as an expression now. What about the expression makes it analyzable at runtime as opposed to the Func? It was my understanding that all Lambdas are compiled into IL and optimized away (which is why you can't use them in Immediate window, etc)?
Expressions compile into object tree instantiations. You can do that yourself. Example: Expression.Constant(1234).
I clarify: lambdas have a C# specific type that does not exist in the CLR. They are convertible to IL Func's AND to Expression's. So they react to context in a well-defined way. Hope that helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.