Доброго времени суток, %username%! Вот и я решился на написание статьи на данном ресурсе. Речь пойдет о доступе к данным из приложений написанных на .NET, в частности на языке C#. Все мои мысли, и во что они в итоге вылились, я попытаюсь изложить под катом. Добро пожаловать!
Под СУБД в статье будем понимать реляционную СУБД. Забегая вперед, скажу, что представленная библиотека (фреймворк) не является заменой Entity Framework, не зависит от него и не имеет к нему никакого отношения.
Тем не менее, оттолкнёмся от вышеупомянутого фреймворка. Одна из его идей – попытка (и весьма удачная) введения абстракции доступа к данным. Иными словами уход от конкретной СУБД.
Каждая СУБД имеет свои плюсы и свои минусы: некоторые имеет одни возможности, некоторые другие; некоторые делают хорошо одно, другие – другое и т.д. Давайте теперь представим, что взвесив все «за» и «против» мы выбрали некую СУБД для реализации какого-то грандиозного (или не очень) проекта и решили писать всё это с использованием… ADO.NET.
Плюсы ADO.NET:
Минусы ADO.NET (предпосылки к реализации проекта):
Ввероятнее всего читатель уже догадался, что мы будем думать как избавляться от вышеупомянутых недостатков. Поговорим о том, что является ключом к реализации всего проекта.
Начнем по порядку.
Проект уже можно опробовать (см. ссылки ниже). Имеется поддержка Linq! Проект в альфа-версии, поэтому код пока неидеален.
Что планируется добавить:
Ссылки:
» Проект WildData на GitHub.
» Nuget-пакет WildData.
» Nuget-пакет WildData (реализация для PostgreSQL).
» Очень простой пример использования фреймворка.
Строго прошу не судить. Это моя первая статья на хабрахабре. Спасибо за внимание!
P.S. По всем вопросам прошу в личку и комментарии.
Под СУБД в статье будем понимать реляционную СУБД. Забегая вперед, скажу, что представленная библиотека (фреймворк) не является заменой Entity Framework, не зависит от него и не имеет к нему никакого отношения.
Тем не менее, оттолкнёмся от вышеупомянутого фреймворка. Одна из его идей – попытка (и весьма удачная) введения абстракции доступа к данным. Иными словами уход от конкретной СУБД.
Каждая СУБД имеет свои плюсы и свои минусы: некоторые имеет одни возможности, некоторые другие; некоторые делают хорошо одно, другие – другое и т.д. Давайте теперь представим, что взвесив все «за» и «против» мы выбрали некую СУБД для реализации какого-то грандиозного (или не очень) проекта и решили писать всё это с использованием… ADO.NET.
Плюсы ADO.NET:
- полный контроль над запросами;
- относительная простота: создать подключение, создать транзакцию (опционально), создать команду, добавить текст запроса и параметры, запустить, считать данные (опционально);
- есть поддержка практически для любой СУБД.
- тесное взаимодействие с СУБД (например, поддержка таких «нестандартных» типов данных как координаты, JSON и т.д.).
Минусы ADO.NET (предпосылки к реализации проекта):
- для каждой модели необходимо каждый раз заново писать код для чтения, добавления и изменения записи в БД – проще говоря отображения объекта на запись в таблице, представлении т.д. и, наоборот, отображение записи на объект;
- Нет абстрагирования как в Java (хотя есть DbConnection/DbCommand и другие классы, но часто используются конкретные типы, например SqlConnection/SqlCommand);
- Нет универсальной поддержки работы с пакетом записей (добавление, обновление, добавление или обновление, удаление);
Ввероятнее всего читатель уже догадался, что мы будем думать как избавляться от вышеупомянутых недостатков. Поговорим о том, что является ключом к реализации всего проекта.
Начнем по порядку.
- Что же мы можем сделать для того, чтобы написать этот код один раз? В первую очередь заметим, что костяк для чтения одного или нескольких объектов остается неизменным вне зависимости от того что это за объект и какие поля он содержит. Это означает, что нам необходима универсальная функция чтения одного объекта. То же верно для добавления и обновления записи.
Как такая функция должна быть написана? Первое что приходит на ум – Reflection. Допустим. Но у Reflection есть один существенный недостаток – он медленный. Если при чтении/добавлении/изменении/удалении одного объекта быстродействие просядет несущественно, то при большом количестве объектов накладные расходы будут ощутимы.
На помощь нам придут Expression'ы и возможность их компиляции «на лету». Идея состоит в том, что тело функции генерируется, компилируется и ссылка на нее сохраняется в виде делегата. Делать это необходимо только один раз – при инициализации.
С чем должны работать функции? С тремя сущностями:
- объект как таковой (модель);
- объект чтения данных (например, SqlDataReader);
- коллекция параметров (например, SqlParameterCollection).
Для того, чтобы точка генерация данных функций была едина, введены следующие интерфейсы обёрток: IDbParameterCollectionWrapper и IReaderWrapper (см. ссылку на репозиторий проекта ниже). Для каждой СУБД необходимо реализовывать эти интерфейсы индивидуально. Забегая вперед: фреймфорк нацелен в первую очередь на скорость работы, поэтому в ряде случаев используется отложенная («ленивая») инициализация. Так же фреймфорк содержит несколько вспомогательных атрибутов для бóльшей гибкости (например, вычисляемые поля, обязательные поля и т.д.).
- Вся общая часть фреймфорка вынесена в отдельный общий проект. Для пользователя видны в основном интерфейсы. Крайне рекомендуется пользоваться только интерфейсами.
- Пакетная работа с записями пока не реализована, но это уже «дело техники».
Проект уже можно опробовать (см. ссылки ниже). Имеется поддержка Linq! Проект в альфа-версии, поэтому код пока неидеален.
Что планируется добавить:
- больше тестов;
- поддержка других баз данных: в первую очередь SQL Server, MySQL;
- поддержка Microsoft.AspNet.Identity.
Ссылки:
» Проект WildData на GitHub.
» Nuget-пакет WildData.
» Nuget-пакет WildData (реализация для PostgreSQL).
» Очень простой пример использования фреймворка.
Строго прошу не судить. Это моя первая статья на хабрахабре. Спасибо за внимание!
P.S. По всем вопросам прошу в личку и комментарии.