WildData: легкий фреймворк доступа к данным

Доброго времени суток, %username%! Вот и я решился на написание статьи на данном ресурсе. Речь пойдет о доступе к данным из приложений написанных на .NET, в частности на языке C#. Все мои мысли, и во что они в итоге вылились, я попытаюсь изложить под катом. Добро пожаловать!

Под СУБД в статье будем понимать реляционную СУБД. Забегая вперед, скажу, что представленная библиотека (фреймворк) не является заменой Entity Framework, не зависит от него и не имеет к нему никакого отношения.

Тем не менее, оттолкнёмся от вышеупомянутого фреймворка. Одна из его идей — попытка (и весьма удачная) введения абстракции доступа к данным. Иными словами уход от конкретной СУБД.

Каждая СУБД имеет свои плюсы и свои минусы: некоторые имеет одни возможности, некоторые другие; некоторые делают хорошо одно, другие — другое и т.д. Давайте теперь представим, что взвесив все «за» и «против» мы выбрали некую СУБД для реализации какого-то грандиозного (или не очень) проекта и решили писать всё это с использованием… ADO.NET.

Плюсы ADO.NET:

  1. полный контроль над запросами;
  2. относительная простота: создать подключение, создать транзакцию (опционально), создать команду, добавить текст запроса и параметры, запустить, считать данные (опционально);
  3. есть поддержка практически для любой СУБД.
  4. тесное взаимодействие с СУБД (например, поддержка таких «нестандартных» типов данных как координаты, JSON и т.д.).

Минусы ADO.NET (предпосылки к реализации проекта):
  1. для каждой модели необходимо каждый раз заново писать код для чтения, добавления и изменения записи в БД — проще говоря отображения объекта на запись в таблице, представлении т.д. и, наоборот, отображение записи на объект;
  2. Нет абстрагирования как в Java (хотя есть DbConnection/DbCommand и другие классы, но часто используются конкретные типы, например SqlConnection/SqlCommand);
  3. Нет универсальной поддержки работы с пакетом записей (добавление, обновление, добавление или обновление, удаление);

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

Начнем по порядку.

  1. Что же мы можем сделать для того, чтобы написать этот код один раз? В первую очередь заметим, что костяк для чтения одного или нескольких объектов остается неизменным вне зависимости от того что это за объект и какие поля он содержит. Это означает, что нам необходима универсальная функция чтения одного объекта. То же верно для добавления и обновления записи.

    Как такая функция должна быть написана? Первое что приходит на ум — Reflection. Допустим. Но у Reflection есть один существенный недостаток — он медленный. Если при чтении/добавлении/изменении/удалении одного объекта быстродействие просядет несущественно, то при большом количестве объектов накладные расходы будут ощутимы.

    На помощь нам придут Expression’ы и возможность их компиляции «на лету». Идея состоит в том, что тело функции генерируется, компилируется и ссылка на нее сохраняется в виде делегата. Делать это необходимо только один раз — при инициализации.

    С чем должны работать функции? С тремя сущностями:

    • объект как таковой (модель);
    • объект чтения данных (например, SqlDataReader);
    • коллекция параметров (например, SqlParameterCollection).

    Для того, чтобы точка генерация данных функций была едина, введены следующие интерфейсы обёрток: IDbParameterCollectionWrapper и IReaderWrapper (см. ссылку на репозиторий проекта ниже). Для каждой СУБД необходимо реализовывать эти интерфейсы индивидуально. Забегая вперед: фреймфорк нацелен в первую очередь на скорость работы, поэтому в ряде случаев используется отложенная («ленивая») инициализация. Так же фреймфорк содержит несколько вспомогательных атрибутов для бóльшей гибкости (например, вычисляемые поля, обязательные поля и т.д.).
  2. Вся общая часть фреймфорка вынесена в отдельный общий проект. Для пользователя видны в основном интерфейсы. Крайне рекомендуется пользоваться только интерфейсами.
  3. Пакетная работа с записями пока не реализована, но это уже «дело техники».

Проект уже можно опробовать (см. ссылки ниже). Имеется поддержка Linq! Проект в альфа-версии, поэтому код пока неидеален.

Что планируется добавить:

  • больше тестов;
  • поддержка других баз данных: в первую очередь SQL Server, MySQL;
  • поддержка Microsoft.AspNet.Identity.

Ссылки:

» Проект WildData на GitHub.
» Nuget-пакет WildData.
» Nuget-пакет WildData (реализация для PostgreSQL).
» Очень простой пример использования фреймворка.

Строго прошу не судить. Это моя первая статья на хабрахабре. Спасибо за внимание!

P.S. По всем вопросам прошу в личку и комментарии.

Комментарии (3)

  • 19 декабря 2016 в 01:29

    +1

    Рекомендую обновить readme на гитхабе. Сейчас там нет никакой информации об использовании. Я понимаю, что есть тесты, но первое впечатление о проекте складывается именно по readme-файлу, как мне кажется
    • 19 декабря 2016 в 01:30

      –1

      Благодарю! Вы правы, readme стоит обновить. Столько всего хотелось сделать, что до него руки так и не дошли пока…
      • 19 декабря 2016 в 04:02

        0

        Обновил readme.

© Habrahabr.ru