Веб-разработка на .NET // dotnet web dev
94 subscribers
1 photo
34 links
Разрабатываю на .NET. В этом канале пишу заметки о программировании в целом и разработке на дотнете в частности

Электропочта: [email protected]
Электросайт: boyarincev.net
Download Telegram
Оказывается Entity Framework Core может использовать INotifyPropertyChanged интерфейс для того, чтобы напрямую узнавать о изменениях в моделях и не использовать снапшот данных для их поиска. Думаю, что это можно попробовать использовать в высокопроизводительных сценариях.

#entityframework
Статья с разбором продвинутых техник использования проекций в Entity Framework Core.
1. Как хранить проекции для их переиспользования.
2. Как хранить и использовать вложенные проекции для проекций.
3. И наконец самое интересное - способ создания вложенных проекций не для коллекций, а для одиночных сущностей (для вложенной проекции одиночной сущности нельзя вызвать Select, а значит и нельзя сделать проекцию.

#entityframework
Ну и наконец две статьи в которых рассказывается, как можно изменить генерацию SQL в Entity Framework Core.

1. Extending SQL Generation in Entity Framework Core
2. Реализуем свой оператор в Entity Framework Core

#entityframework
Поговорим про производительность Entity Framework.

Во-первых существует whitepaper по производительности EF, из которого можно узнать очень много грязных низкоуровневых подробностей работы EF, но он не обновлялся для EF Core, поэтому в чём-то не актуален. Хотя концептуально всё-равно полезен, если у вас возникнет необходимость супер-оптимизировать и скорость работы EF Core тоже:

Performance considerations for EF 4, 5, and 6

Но whitepaper никак не решает проблему того, что Entity Framework в принципе не приспособлен для массовых операций изменения данных - массовых Insert, Update и Delete. Тут проблема лежит в двух плоскостях - тормозит DbContext и тормозит сама база данных, так как EF производит все изменения отдельными sql запросами (хотя и в рамках одного физического запроса к базе данных).

Техники работы с контекстом, чтобы он меньше тормозил при Insert рассмотрены в этой статье Rick Strahl: Entity Framework and slow bulk INSERTs
И техника с пересозданием DbContext и "пакетным" сохранением описанная там, довольно эффективна, а в этом ответе на SO есть сравнение влияния размера пакетов на скорость сохранения, так чтобы вы могли выбрать оптимальный.

Для ускорения контекста при массовом обновлении и удалении, тоже есть "хаки":
1. Аттачить к контексту "болванки" (сущности, которые на загружались из БД и которых нет в контексте), а затем явно их помечать в контексте как обновлённые или удалённые (через DbContext.Entry), кое-что по этой теме можно найти здесь.
2. Также как при Insert пакетировать сохранение.
3. Также как при Insert отключать автоматический поиск изменений в контексте.

Но самый эффективный путь - это вообще отказаться от использования Entity Framework для массовых операций изменения данных и, например, напрямую использовать SQL.
(Если решите пойти этим путём, то загляните ещё в эту статью, в ней автор рассказывают свою идею как сделать такие SQL-запросы более типизированными.)

А для тех случаев, когда даже SQL тормозит, можно пойти дальше и использовать более производительные способы, которые предоставляет база данных.

Например, вот в этой статье, рассказано, как использовать специальные возможности MSSQL Server для ускорения Insert и Update на уровне базы данных: Entity Framework: повышаем производительность при сохранении данных в БД. Подобную возможность, кстати, предоставляет и PostgreSQL.

Ну и буквально на днях наткнулся на библиотеку Linq2Db у которой есть интеграция с Entity Framework и с помощью которой, судя по всему, без проблем можно будет делать массовый Insert, Update, Delete. Кстати, умеет использовать специальные высокопроизводительные операции специфичные для базы данных. Но предупреждаю, сам её ещё не использовал.

#entityframework
#entityframework

Не помню уже, как велики были возможности логирования в классическом Entity Framework, но у Entity Framework Core с этим точно всё в порядке, статья на эту тему: Настройка логирования в Entity Frmework Core
Про Entity Framework и DDD

Обычно так случалось, что если архитектура у нас по DDD, а проект более менее большой и серьёзный, то мы как правило разделяли доменную и дата модели на две отдельные, потому что Entity Framework в своих ранних версиях накладывал много ограничений и специфичных требований на модели, но в процессе взросления EF эти ограничения становились всё меньше и теперь уже Entity Framework Core позволяет в качестве и доменных и дата моделей использовать одну и ту же модель не идя на компромиссы. А как это делать можно прочитать в статьях Джули Лерман:

1. DDD-Friendlier EF Core 2.0
2. DDD-Friendlier EF Core 2.0, Part 2

Или посмотреть в её выступлении на NDC Conference: Mapping DDD Domain Models with EF Core 2.1

И ещё есть хорошая статья на хабре: Сущности в DDD-стиле с Entity Framework Core

Подход с объединением моделей проще, потому что при использовании отдельных моделей для домена и дата слоя необходимо решить проблему отслеживания изменений в доменных сущностях и правильного переноса этих изменений в дата модели, так чтобы Entity Framework смог сохранить всё корректно. Готовой статьи на эту тему дать не смогу, но, в принципе, эта проблема релевантна проблеме под названием "Работа с отсоединёнными сущностями" - в случае, когда доменные и дата модели разделены, доменные модели это по сути и есть отсоединённые сущности, так что идеи как решить проблему синхронизации доменных и дата моделей можно почерпнуть, изучая как решают проблему работы с отсоединёнными сущностями. А статья на эту тему, например, вот: Доступ к данным - Обработка состояния отсоединенных сущностей в EF всё той же Джули Лерман.

Ну и если говорить о DDD, то ещё можно затронуть тему Спецификаций и в статье ниже отличный пример того, как можно реализовать спецификации для использования в EF: EntityFramework: (анти)паттерн Repository

#entityframework #DDD
How to Cut in iMovie