EF6: Why does the graph return 0, but it returns the returned item?

In this code

using (var db = new DbPerson())
{
    var b = db.People.Create();
    b.Name = "Homer";

    db.People.Add( b );

    Console.WriteLine( "Count: {0}", db.People.Count() );

    foreach (var bb in db.People)
        Console.WriteLine( bb.Name );

    var fb = db.People.Find( b.Id ); // Id is a GUID generated in the Person ctor
                                     //  NOT a DB-generated Identity.
    Console.WriteLine( "Found: {0}", fb != null );

    db.SaveChanges();

    Console.WriteLine( "Count: {0}", db.People.Count() );
}

      

the output looks like this:

Count: 0
Found: True
Count: 1

      

I've seen other posts about Count not being updated prior to being called SaveChanges

. Okay, so this is the "way it works".

My question is specifically about this: why does it Find

return an object from db.People

when it Count()

returns 0, and the enumerator doesn't return any items? Should tags Find

and Count()

act similarly, waiting SaveChanges

before returning objects in the Added state?

What is the reason for this? I am asking because I am writing a lightweight non-SQL provider that should reflect EF actions as much as possible. I can not understand what logic forces the Find

return element that was added, which Count()

, and GetEnumerator()

do not. I need to resolve these situations.

+3


source to share


2 answers


Find()

has a special quality: it will first look at a DbContext object that was recently added but not yet dropped into the database (for example: objects with EntityState.Added

).

Count()

and the enumerator will instead look at the database, which obviously doesn't have anything yet until you name it SaveChanges()

.



Background information

+1


source


If you ask why it is implemented like this: Find

should allow you access to tracked objects by ID that are not in the database. Find

is a rather special method. Maybe it allows you to fetch deleted objects and the documents don't speak. There are other APIs for accessing the tracked object pool.

This is usually a sign of poor use of EF (or a sign of a hack) if you need to mess around with it.



NHibernate had a really useful one Find

: it allowed you to get an object without accessing the database. It returns the proxy. This way you can always pass object objects and almost never ID. Nice abstraction. This is not possible with EF. Find

goes to the database.

+1


source







All Articles