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.
source to share
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()
.
source to share
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.
source to share