Решение является попыткой совместить шаблоны Repository и CQS (Command Query Segregation).
более чистый код, удобство использования, поддержки и расширения. Разделяем логику получения данных и логику изменения данных. Инкапсулируем каждый запрос вместе с его параметрами и соединением с БД в отдельные классы. Кастомизацию каждого запроса (фильтрация, пейджинг, сортировки) также можем задавать самостоятельно. Для каждого запроса существует возможность реализовать как синхронный, так и асинхронный интерфейс. Библиотека основана на Entity Framework 6 / EF.Core. Все сущности библиотеки реализуют некие интерфейсы и, соответвенно, могут быть легко внедрены при разработке с Dependency Injection.
Основной проект библиотеки - DataAccess.Core - Содержит все основные интерфейсы и базовые классы DataAccess.Repository.EFCore - репозиторий инкапсулирующий работу с CRUD запросами к БД на основе EF.Core DataAccess.Repository -репозиторий инкапсулирующий работу с CRUD запросами к БД на основе EF6. Пример работы с библиотекой - DataAccess.Client.EFCore Базовые сущности для работы с подходом CQRS реализованы в DataAccess.CQRS
Единственным условием корректной работы вашего контекста данных с библиотекой - все ваши EF модели должны реализовать данный интерфейс. Если подробнее - иметь поле Id.
Набор методов расширения, позволяющих применять "спецификации" к интерфейсу IQueryable, для кастомизации запроса.
Набор методов, реализующих основные операции с БД. Особенность: типизирован не сам класс, а каждый метод, для того чтобы 1 и тот же экземпляр репозитория можно было использовать для запросов к разным наборам сущностей (DbSet-ам) из контекста.
Generic класс реализующий гибкий CRUD для типа IDbEntity на основе неких спецификаций запроса.
Спецификация (набор параметров) для запроса данных из БД.
Для фильтрации сущностей укажите в спецификации запроса объекты фильтров, реализующие этот интерфейса. Для облегчения задачи предлагается наследоваться от уже готового "базового" фильтра QueryFilterBase.
Для включения в запрос связанных таблиц, передавайте в спецификации объект реализующий IQueryJoin. Для облегчения задачи можно использовать готовый QueryJoinBase, передав в конструктор при инстанциировании правильный набор включаемых таблиц.
Для сортировки результатов запроса в памяти сервера БД, передавайте в спецификации объект реализующий IQueryOrder. Для облегчения задачи можно использовать готовый QueryOrderBase, передав в конструктор при инстанциировании требуемую сортировку.
Пагинация результатов запроса.
Тип "команда" (Command) - любая операция изменяющая данные, может возвращать результат операции. Для наиболее частых операций уже реализованы базовые команды.
Базовый класс для команд добавления/обновления некой сущности типа TEntity. для удобства от него можно (и даже нужно) не наследоваться, а инстанцировать прямо в коде, указывая конкретный тип
Базовый класс для команд удаления некой сущности типа TEntity. для удобства от него можно (и даже нужно) не наследоваться, а инстанцировать прямо в коде, указывая конкретный тип
Тип "запрос" (Query) - операция возвращающая данные, не имеет права ничего менять. Интерфейс IQuery позволяет указать для каждого запроса спецификацию - некий набор параметров, оказывающий влияние на выполнение запроса. Для уже готовых запросов (GetListQuery, GetByIdQuery ...) уже описаны требуемые ими спецификации (QuerySpec, OrderedQuerySpec...). Для создаваемых разработчиками кастомных запросов, вы можете определить набор данных и их использование самостоятельно. В качестве спецификации может выступить абсолютно любой тип, по Вашему желанию.
класс для запросов любых сущностей из БД по Id от него можно (и даже нужно) не наследоваться, а инстанцировать прямо в коде, указывая конкретный тип
класс для запросов сущностей из БД списком Spec - параметры запроса (фильтрация, пагинация, джоин) от него можно (и даже нужно) не наследоваться, а инстанцировать прямо в коде, указывая конкретный тип
public class GetOrderedListQuery<TEntity, TSortKey> : IDbQuery<List, OrderedQuerySpec<TEntity, TSortKey>>
класс для запросов сущностей из БД списком, Spec - паремтры запроса (фильтрация, пагинация, сортировка). от него можно (и даже нужно) не наследоваться, а инстанцировать прямо в коде, указывая конкретный тип
Дальнейшее знакомство с библиотекой рекомендуется продолжать внутри проекта, видя реализацию каждого класса, связи и зависимости.