Entity Framework: Odd things during querying

serverdatabasehitit1

So in THIS POST I talked about how querying worked on a conceptual level but turns out there is something going on that’s not expected. Remember how I said that if the object is in the context, the database won’t be hit? Turns out that isn’t true to an extent. With the help of profiler, I found outconfusing thing or two, and neither have to do with why this is was on the front page of CNN.

Say you for some reason want to select a user like so:

    SiteUser someUser = context.SiteUser.First(role => role.UserID == 1);

WOW THAT IS NEW AND AMAZING!!!117!

Right off the bat, I bet you can guess what happens. If not (You know, if you didn’t read THIS POST or you have difficulties with revolving doors), here’s the idea in script form:

            CONTEXT
    Am I having this Object?

Context looks into its bag, notices it doesn't have the object,
and then looks over at Database with confused look.

            DATABASE
   No but I gots it for you.

Database hands object to Context.  Context looks happy.

            CONTEXT
  I has a object now.

At this point, two things are obvious: I’ve lost it and Context now has a User with an UserID of one and it got this by querying the database. Now suppose for no real reason you want the same user. (Assume it is the same context and the user is already in the context.)

            CONTEXT
    Am I having this Object?

Context looks into his bag and pulls out the object.  Database walks over.

           CONTEXT
    You has object?

            DATABASE
   Yes but I gots it for you.

Database hands object to Context.  Context doesn't take it.

            CONTEXT
  I has it already.

So in this stunning display, we can see that even though the context already has the user, it still asks the database for the thing. How do I know this? Well I used profiler on both statements. What I thought would happen is on the first eh First it would hit the database, hydrate the object, and go on its merry. Second First would just grab it from the context and give it to me. Fact is, it STILL HITS THE DATABASE. Now the next possible idea is that it’s going to the database to see if the record has changed and then will update the object with any changes EXCEPT what has been changed on the object. Yeah not so much. (Although there is a way you can force that, but I’ll post that in the next post) Fact is, it really doesn’t do anything with it as long as you have the default settings. In fact, (FACT FACT FACT FACT) the default settings say that:

Objects that already exist in the object context are not loaded from the data source.
This is the default behavior for queries or when calling the Load method on an
EntityCollection<(Of <(TEntity>)>).

Seems kind of odd that by default something in the context will not be loaded if it’s already there but it still hits the database regardless. So what this default really means is that it may or may not hit the database, but any changes in the database will not be reflected in the object. It really doesn’t mean that the database won’t be queried. Seems kind of odd.

What not good enough? Fine, figure this out.