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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With