Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Эффективная работа с данными в корпоративных пр...

CUSTIS
November 01, 2018

Эффективная работа с данными в корпоративных приложениях на .NET: DAL, ORM, Bulk-операции

Выступление Владислава Иофе, нашего архитектора приложений, на CUSTIS Meetup (Москва, 1 ноября 2018).

CUSTIS

November 01, 2018
Tweet

More Decks by CUSTIS

Other Decks in Programming

Transcript

  1. Эффективная работа с данными в корпоративных приложениях на .NET: DAL,

    ORM, Bulk-операции Владислав Иофе Архитектор приложений
  2. Аннотация В спорах о необходимости выделения Data Access Layer и

    использования ORM сломано немало копий. Доклад будет посвящен нашим подходам к работе с данными. Вы узнаете, какие возможности работы с множеством данных предоставляют различные провайдеры ADO.NET, зачем вам Batch- и Bulk-операции, как шутя обрабатывать десятки и сотни миллионов записей, что такое гибридные DAL и зачем мы используем три ORM в одном продукте. 2
  3. План  Некоторые паттерны  LINQ  DAL  А

    как у нас?  Retrieving and Modifying Data in ADO.NET  Обсуждение 3
  4. Query Object 4  Абстрагирует от SQL  Интерпретирует один

    «язык» в другой Например, из Criteria API в SQL  EF: ObjectQuery<T>  NH: QueryOver
  5. Active Record  Объединяет доменный объект и доступ к данным

     Может содержать доменную логику  Инкапсулирует CRUD-логику  Не решает задачу массовых CRUD-операций 6
  6. Data Mapper  Доменный объект и доступ к данным разделены

    → однонаправленная зависимость  Соблюдается SOLID  Лучше подходит для нетривиальных соответствий (например, объекты с коллекциями)  Не решает задачу массовых CRUD-операций 7
  7. Repository  Коллекция доменных объектов в памяти  Инкапсулирует массовые

    CRUD-операции  На вход принимает условие отбора объектов коллекции  Доменный объект и доступ к данным разделены → однонаправленная зависимость 8
  8. Repository (2) Repository «вытягивает» еще ряд паттернов-возможностей  Identity Map

     Caching  Data  Query  Lazy Load  Unit of Work  Change-Tracking 9
  9. План  Некоторые паттерны  LINQ  DAL  А

    как у нас?  Retrieving and Modifying Data in ADO.NET  Обсуждение 10
  10. А что с LINQ(-to-Database)?  Основа – IQueryable  IQueryable

    реализует паттерн Query Object  Реализация в ORM – часто симбиоз Repository и Query Object 11
  11. Использование IQueryable  Подходит для ориентированных на данные протоколов (OData),

    в том числе интеграций и пользовательских интерфейсов  UI  Открытые данные https://apidata.mos.ru/  Интеграция с 1С и SAP  Если нужен IQueryable, то описания сущностей, DML и Queryable будут (широким) контрактом DAL и (или) бизнес-логики. Даже в этом случае маппинги, преобразования – в отдельной сборке. Следует контролировать зависимости (их отсутствие) от сборок ORM  Другой подход: репозитории с тематическими методами (например, GetByOriginSupply) 12
  12. План  Некоторые паттерны  LINQ  DAL  А

    как у нас?  Retrieving and Modifying Data in ADO.NET  Обсуждение 13
  13. ORM разных сортов  Full ORM  Entity Framework 

    NHibernate  Micro ORM  Dapper  PetaPoco  Insight.Database  Скорость выборки первой записи  Full ORM: 150–250 мс  Micro ORM: 80 мс 14
  14. Классы ORM и паттерны  EF: DbContext – Unit of

    Work, DbSet – Repository с LINQ  NH: ISession – все в одном флаконе  NH: IStatelessSession – «стать Micro ORM» 15
  15. DAL: за и против 17 За Против  Разделение ответственности

    (SoC)  Более «чистый» код бизнес-логики  Разделение разработчиков по компетенциям  Data-centric приложение (ETL и др.)  Интероперабельность, замена реализации DAL  Лишний слой абстракции добавляет сложности  Нельзя не думать о том, какие запросы породит бизнес-логика
  16. DAL: объективно  Смотреть на требования (Performance vs Maintainability) 

    Характер самих данных различается  Full-Stack vs Specialist  Тип и особенности хранения часто «протекают» на потребителя 18
  17. DAL: гибриды Разные домены имеют ограниченные связи  Могут быть

    разделены в продукте или приложении  Могут быть реализованы в разных архитектурах  Не говоря уже о разных DAL Так почему бы не комбинировать? 19
  18. DAL: тематические репозитории  Репозитории могут предоставлять понятный и довольно

    узкий контракт для бизнес-логики приложения  Муторно, но несложно  Код бизнес-логики читается реально легко  Далеко не все возможные поисковые методы будут нужны  Но если потребитель приложения сам строит запрос (например, OData), прокинуть IQueryable насквозь – здравое решение 20
  19. План  Некоторые паттерны  LINQ  DAL  А

    как у нас?  Retrieving and Modifying Data in ADO.NET  Обсуждение 21
  20. А как у нас?  По-разному. Нет обязательной и узаконенной

    «DAL-религии»  Архитектор продукта решает  В последних продуктах преобладают собственные репозитории поверх ORM с «тематическими» методами и иногда с IQueryable  В текущем продукте используем несколько ORM (NHibernate, Dapper), а еще один достался в наследство  Code-First 22
  21. План  Некоторые паттерны  LINQ  DAL  А

    как у нас?  Retrieving and Modifying Data in ADO.NET  Обсуждение 23
  22. Retrieving and Modifying Data in ADO.NET  Работа с БД

     IDbConnection  IDbCommand  IDataReader  Хранение в памяти и обработка*  (Db)DataAdapter  DataSet * Работа с этими классами скорее характерна для Table Module, Transaction Script и DAL 24
  23. Пакетная обработка в провайдерах  С извлечением данных все хорошо!

     Но сохранять поштучно?!  Ответ: int DbDataAdapter.UpdateBatchSize  Batch [bæʧ] – 1) группа; серия; партия; пакет 2) формировать, накапливать  Пакетная обработка повышает производительность за счет уменьшения roundtrip  Поддерживается, если автор провайдера пожелает  UpdateBatchSize должен быть разумного размера. Большое значение снижает производительность.  А если не использовать DbDataAdapter? 25
  24. Пакетная обработка в провайдерах. Под капотом  System.Data.SqlClient.SqlCommand Текст команды

    – множество запросов  Через точку с запятой  DML оборачивается в вызовы sp_executesql  int Oracle.DataAccess.Client.OracleCommand.ArrayBindCount Array Binding – один текст команды, параметры – массивы. СУБД организует цикл на своей стороне  Производительность Row-by-row и Batch может отличаться на два порядка 26
  25. А где обещанные миллионы?  Требуется импортировать миллионы записей 

    Особенности СУБД существенно различаются  Как следствие в ADO.NET не стандартизовано, но выглядит похоже во многих провайдерах  Bulk [bʌlk] – большое количество, большой массив данных, груда, масса  Утилиты, в SQL Server – bcp, в Oracle Database – SQL*Loader 27
  26. Вопросы для обсуждения  Когда (не) надо выделять слой доступа

    к данным?  Покрывает ли ORM все потребности в DAL?  Почему разработчики .NET оказались в привилегированном положении?  Что DAL может предоставить для миграции баз данных? 30