Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Entity Framework's DbContext.Find() generate a query with select top 2?

Why does the Entity Framework's DbContext.Find() generate a query with select top 2 and a derived table? By definition, the query is looking up by primary key which should be unique.

like image 773
Jon Anderson Avatar asked Oct 19 '11 14:10

Jon Anderson


1 Answers

Find checks first if the entity with the given key is already in the context. If not it queries the database. Possibly it uses in this case a LINQ query using SingleOrDefault. SingleOrDefault translates to SELECT TOP 2 to be able to throw an exception if the result has more than one entity.

So, why doesn't Find use FirstOrDefault (which would translate to SELECT TOP 1). I don't know, but I would guess that Find wants to check that the entity is really unique in the database. It should - because it's the primary key the query uses - but model and database could be out of sync because someone changed the primary key in the database, for example: added a column to a composite key in the database but not in the model.

Really just a hypothesis. Only EF development team probably can answer what's exactly the reason.

Edit

If I do this as described above (add column to composite key in DB and add a record with the same value in the first key column) and call then Find, I get the exception...

Sequence contains more than one element

...and this stacktrace:

//...
System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)
System.Data.Entity.Internal.Linq.InternalSet`1.FindInStore(
    WrappedEntityKey key, String keyValuesParamName)
System.Data.Entity.Internal.Linq.InternalSet`1.Find(Object[] keyValues)
System.Data.Entity.DbSet`1.Find(Object[] keyValues)

So, it looks that Find indeed uses SingleOrDefault.

like image 108
Slauma Avatar answered Oct 04 '22 20:10

Slauma