вторник, 12 мая 2020 г.

фичи Entity Framework Core, которых нет в Entity Framework 6

кратко изучил новые возможность EF Core. на основе таблицы: https://docs.microsoft.com/en-us/ef/efcore-and-ef6/

есть прям крутые штуки!


  • Constructors with parameters - если конструктор сущности содержит параметры, по имени соответствующие полям-участникам модели - вместо полей значения передаются в параметры конструктора
  • Property value conversions -  можно делать промежуточную конвертацию между значениями в колонках БД и свойствами объекта. к примеру, преобразовывать значения перечислений в строку и хранить в БД в строковом виде. можно делать свои преобразователи, и есть ряд стандартных уже готовых преобразователей. например, преобразователь энама в строку
  • Mapped types with no keys - можно объявлять в контексте сущность на основе БД-View. и потом использовать ее как базу для построения запросов. при какой-то там поддержке со стороны БД дыже будут отслеживаться изменения.
  • Shadow state properties - блин, круть! позволяет к таблицам сущности добавлять дополнительные служебные колонки, которые не нужны в классе сущности / противоречат OOP/DDD (например, LastUpdated, RowVwersion...)
  • Alternate keys - возможность использовать ~осмысленное поле в качестве ключа. и внешние ключи чтоб на него ссылались (или на них)
  • возможность генерировать ключи для новых сущностей на клиенте (в частности, алгоритм hiLo) - для новых сущностей сразу известен их ID, не обязательно сначала сохранять сущность в БД
  • Global query filters - возможность применять фильтр к ~сущностям-таблицам ( https://docs.microsoft.com/en-us/ef/core/querying/filters). к примеру, чтоб в в коллекции context.MyEntities не включались вопросы с флагом IsDeleted = true
  • Field mapping https://docs.microsoft.com/en-us/ef/core/modeling/backing-field?tabs=data-annotations - вроде как, EF - будет писать в приватное поле, а не в свойство, если найдет поле для свойства по конвенции (типа, Url/_url). и читать, наверное, тоже. типа, чтоб не задевать возможную логику, заложенную в геттерах-сеттерах
  • Nullable reference types https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types - я так понял, с nullable reference types в контексте EF Core больше гемора. но не знаю, надо будет на практике опробовать
  • Raw SQL queries: Composing with LINQ https://docs.microsoft.com/en-us/ef/core/querying/raw-sql - ауфф! можно получать коллекцию сущностей  из чистого SQL-запроса, и эту коллекцию можно использовать в построении дальнейших запросов
  • Batching of statements -  https://www.talkingdotnet.com/what-is-batching-of-statement-in-entity-framework-core/ - оказывается, в EF6 , когда выполнялась команда SaveChanges, на каждый создаваемый или изменяемый объект выполнялся отдельный запрос insert или update. в Core изменения по нескольким сущностям выполняются одним запросом
  • Disconnected graph low-level APIs https://www.entityframeworktutorial.net/efcore/working-with-disconnected-entity-graph-ef-core.aspx - улучшена (видимо) возможность сначала создавать графы объектов в памяти, а потом коннектить их к дата-контексту
  • DbContext pooling - https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#dbcontext-pooling - ну вот, пул контекстов. используется на уровне DI. как я понял, когда вышли из скоупа - все изменения сохраняются (context.savechanges), все EF-поля контекста ресетятся, и контекст кладется  обратно в пул
  • In_Memory DB Provider - для тестов!

понедельник, 4 мая 2020 г.

хранимые процедуры (stored procedures) - стоит ли применять?


Покопался в интернете на тему того, стоит ли применять хранимые процедуры , и в каких случаях.
находил аргументы как за, так и против. 

Вот что я для себя выяснил:

  • СУБД гораздо менее дружелюбны к масштабированию ( https://habr.com/ru/post/487622/, один из комментов)
  • неудобство контроля версий. прям, печаль, люди опытом делятся, какое решение кто нашел. целая буча, в общем
  • скудные возможности языка
  • как следствие из предыдущего - тяжело/не возможно следовать принципам ООП - на мой взгляд, самый тяжкий из грехов
  • проблемы с юнит-тестированием (вытекает из предыдущего) (хотя, другие говорят, что как-то можно)
  • не скейлятся (ну или скейлятся как-то проблемно. типа, они ~"изначально должны быть заточены на шардинг", чтоб их можно было скейлить). это, кстати, чаще других упоминается.
  • тяжелее прописывать сложную логику 
  • IDE для разработки ХП, возможно, будет лажовым (зависит от СУБД)
  • язык хранимок распологает к копипасте 


сам я не использую хранимки, поэтому делал упор на аргументы против :)
про аргументы "за" у меня сложилось впечатление, что большинство их них можно не принимать во внимание при наличии 3-звенной архитектуры / бизнес-слоя / сервиса бизнес-логики. Единственный убедительный для меня аргумент - оптимизация. для себя я сделал вывод, что, как и в случае с другой оптимизацией, хранимые процедуры нужно применять только в "бутылочных горлышках системы". и заплатить за это, как и в случае прочей оптимизации, придется простотой поддерживаемости кода. в общем, без необходимости лучше не использовать.

полезные ссылки: