Как работать с Entity Framework?
Что проверяют
Понимаете ли вы отслеживание изменений и умеете ли избегать типичных проблем производительности.
Как отвечать
EF Core это ORM: сущности отображаются на таблицы, запросы пишутся на LINQ, изменения сохраняются через SaveChanges.
Ключевое понятие это контекст и отслеживание изменений. Загруженные сущности запоминаются, и при сохранении EF сам определяет, что изменилось, и генерирует нужные команды. Отсюда правила:
- контекст короткоживущий: один на запрос (
Scoped), а не синглтон. Он не потокобезопасен, и накопленное состояние растёт; AsNoTrackingдля запросов только на чтение: отслеживание не нужно, и это заметно быстрее на больших выборках;IncludeиThenIncludeпротив N+1: без них обращение к навигационному свойству вызовет отдельный запрос на каждую строку. Ленивая загрузка по умолчанию выключена именно поэтому;- проекция через
Selectв DTO вместо загрузки полных сущностей: меньше колонок, меньше памяти; - миграции:
Add-MigrationиUpdate-Database, файлы в репозитории, автогенерация читается глазами перед применением.
Обязательно про клиентское вычисление: EF Core переводит выражение в SQL, а что не может перевести, начиная с третьей версии выбрасывает как ошибку, а не считает в памяти молча. Вызов своего метода внутри Where это как раз такой случай.
Для проверки того, что реально ушло в базу, включают логирование запросов. Это первое, что делают при жалобах на скорость.
Где спотыкаются
Держат контекст долго или делят между потоками.
Получают N+1 и не смотрят в лог сгенерированных запросов.
Загружают полные сущности там, где нужны два поля.
Вызывают ToList в середине цепочки и вытаскивают таблицу целиком в память.