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