В качестве альтернативы, запустите трассировку для базы данных, чтобы зафиксировать операторы SQL, фактически выполняющиеся с ней, используйте точку останова в коде, запустите трассировку и выполните строку чтения. Трассировка покажет точные операторы SQL, которые выполняются. Затем вы можете скопировать эти заявления в SSMS, чтобы проверить, что они возвращают. Простым инструментом трассировки, который я использую для SQL Server, является ExpressProfiler, созданный еще в те дни, когда была включена трассировка для SQL Server Express. Хотя я рекомендую собирать его из исходного кода (https://github.com/ststeiger/ExpressProfiler), а не из любого установщика, такого как Sourceforge. SSMS имеет профилировщик в Tools / SQL Server Profiler, который по умолчанию захватывает намного больше шума. Любой инструмент имеет неоценимое значение для исследования как странности EF, так и производительности.
, если context.Books.Where(b => b.ID == 1).SingleOrDefault()
возвращает #null, я бы посмотрел, что SQL будет зафиксировано для этого оператора в вашей базе данных. Сравните это с b => b.ID == 2
.
Если ваша трассировка ничего не захватывает ни для 1, ни для 2, но вы видите результирующие данные для сценария ID = 2, тогда объяснение будет состоять в том, что ваш DbContext не указывает на базу данных / сервер, о которой вы думаете, или что-то не так с вашей настройкой DbContext.
Если ваша трассировка захватывает что-то для 1 и 2, но вы видите данные только для # 2, проверьте, что запрос для # 1 выполняется и возвращает данные. Если запрос выглядит корректным, но ваш код ничего не видит для идентификатора №1, то каким-то образом ваш DbContext находится в состоянии, когда идентификатор №1 удален. Я бы добавил код, чтобы проверить ChangeTracker DbContext, чтобы выяснить, есть ли запись для # 1, которая находится в состоянии сущности Removed. Возможно, у вас запущен код, неожиданно каскадный для удаления, но SaveChanges не был вызван или не был успешным. Длительно работающие экземпляры DbContext подвержены такого рода проблемам.
Проверьте следующее:
вместо
var result = context.Books.where(b => b.ID == 1).FirstOrDefault();
используйте это:
using(var testContext = new MyDbContext())
{
var result = testContext.Books.where(b => b.ID == 1).SingleOrDefault();
}
Подставляя MyDbContext
в ваше приложение DbContext. Это устраняет любые забавные дела с длительным состоянием DbContext. Контекст все еще может выполнять SQL, но возвращать то, что находится в кэшированном состоянии.
Примечание. При запросе данных выберите SingleOrDefault
вместо FirstOrDefault
, если ожидаете результаты 0..1. Операции типа First
должны использоваться только в том случае, если вы ожидаете 0..много, но заботитесь только о первом результате, и их всегда следует использовать с условием Order By, чтобы обеспечить предсказуемое упорядочение.