Find
сначала проверяет, находится ли объект с данным ключом в контексте. Если нет, он запрашивает базу данных. Возможно, он использует в этом случае запрос LINQ, используя SingleOrDefault
. SingleOrDefault
переводится в SELECT TOP 2
, чтобы иметь возможность вызвать исключение, если в результате имеется более одного объекта.
Итак, почему Find
не использует FirstOrDefault
(что означает SELECT TOP 1
). Я не знаю, но я бы предположил, что Find
хочет проверить, что сущность действительно уникальна в базе данных. Он должен - потому что это первичный ключ, используемый запросом, - но модель и база данных могут быть не синхронизированы, потому что кто-то изменил первичный ключ в базе данных, например: добавил столбец в составной ключ в базе данных, но не в модели.
На самом деле просто гипотеза. Только команда разработчиков EF, вероятно, может ответить, в чем причина.
Редактировать
Если я сделаю это, как описано выше (добавьте столбец к составному ключу в БД и добавьте запись с тем же значением в первом столбце ключа) и вызовите Find
, я получу исключение ...
Последовательность содержит более одного элемента
... и эта трассировка стека:
//...
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)
Итак, похоже, что Find
действительно использует SingleOrDefault
.