问题
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.
回答1:
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
.
来源:https://stackoverflow.com/questions/7822877/why-does-the-entity-frameworks-dbcontext-find-generate-a-query-with-select-to