[Из песочницы] OdataToEntity легкий способ создания .Net Core OData сервисов

8c00135f5bdf4677b579bd886ddc3d1f.png

Когда вышел .Net Core, старая версии OData ASP.NET Web API оказалась несовместимой с новой платформой. Этот фатальный недостаток позволил мне создать свою реализацию OData на платформе .Net Core. В результате творческого переосмысления предыдущей реализации пришло понимание, что она страдала от переусложненного дизайна с большим количеством ненужных абстракций. Возникла идея создать простую в использовании, требующую минимального кодирования библиотеку. Представляю вашему вниманию OdataToEntity, библиотеку создания OData сервисов без написания кода, нужен только контекст доступа к данным. Как следствие, для упрощения дизайна api было принято решения не использовать в коде интерфейсы, при этом библиотека имеет полное покрытие тестами. Для уменьшения внешних зависимостей библиотека отвязана от http, что позволяет реализовать OData поверх любого транспорта. Это чудо инженерной мысли собирается под Framework 4.6.2 или .Net Core 1.1. и использует Microsoft.OData.Core 7.0. Поддерживаются следующие контексты данных:


  1. Entity Framework 6.1
  2. Entity Framework Core 1.1
  3. Linq2Db

Как это работает


По контексту данных строится OData Entity Data Model (EDM) модель описания данных предоставляемых вашим сервисом. На вход библиотеке подается OData запрос или сущности модели сериализованные в JSON. В случае запроса он c помощью Microsoft.OData.Core (ODataLib) парсится в представление ODataLib, которое транслируется в обычное дерево выражений и затем передается в контекст доступа к данным, выполняет запрос к базе данных и полученные сущности сериализуются в JSON. В случае подачи на вход JSON он c помощью ODataLib десериализуется в сущности, которые добавляются в контекст доступа к данным и сохраняются в базе данных.


Поддерживаются параметры запросов


Параметры запросов
  1. $apply (filter, groupby, aggregate (average, countdistinct, max, min, sum))
  2. $count
  3. $filter
  4. $orderby
  5. $select
  6. $skip
  7. $top
  8. lamda any
  9. lambda all

Функции
  1. cast
  2. ceiling
  3. concat
  4. contains
  5. day
  6. endswith
  7. floor
  8. fractionalseconds
  9. hour
  10. indexof
  11. length
  12. minute
  13. month
  14. round
  15. second
  16. startswith
  17. substring
  18. tolower
  19. toupper
  20. trim
  21. year

Примеры запросов можно посмотреть в тестах .


Поддерживается также batch change set пакетное добавление, удаление, изменение сущностей.
Каждый OData запрос покрыт соответствующим тестом, всего имеется 65 тестов (xunit).


a097f722d37a43308708800ed29e8598.png

Пример использования


Пример выполнения OData запроса состоит всего из шести строчек. Предположим у вас есть Microsoft.EntityFrameworkCore .DbContext с именем OrderContext.


//Создаем адаптер доступа к данным, где OrderContext ваш DbContext
var dataAdapter = new OeEfCoreDataAdapter();
//Содаем OData EDM модель
IEdmModel edmModel = OeEdmModelBuilder.BuildEdmModel(dataAdapter);
//Создаем парсер запросов
var parser = new OeParser(new Uri("http://dummy"), dataAdapter, edmModel);
//Сам запрос
var uri = new Uri("http://dummy/Orders?$select=Name");
//Результат выполнения запроса
var response = new MemoryStream();
//Выполнение запроса
await parser.ExecuteQueryAsync(uri, OeRequestHeaders.Default, response, CancellationToken.None);

Пример сохранения новых сущностей в базе данных также состоит из шести строчек. Предположим сами сущности уже сохранены в файле Batches\Add.batch


//Создаем адаптер доступа к данным, где OrderContext ваш DbContext
var dataAdapter = new OeEfCoreDataAdapter();
//Содаем OData EDM модель
IEdmModel edmModel = OeEdmModelBuilder.BuildEdmModel(dataAdapter);
//Создаем парсер запросов
var parser = new OeParser(new Uri("http://dummy"), dataAdapter, edmModel);
//Сериализованные сущности в формате JSON UTF8
var request = new MemoryStream(File.ReadAllBytes("Batches\\Add.batch"));
//Результат выполнения запроса
var response = new MemoryStream();
//Выполнение запроса
await parser.ExecuteBatchAsync(request, response, CancellationToken.None);

Другие примеры можно найти в папке test


Структура исходного кода


Исходный код разделен на две части в папке source сама библиотека и сборки доступа к различным источникам данных, в папке test тесты и примеры кода.
Файлы солюшенов в папке sln
Сама библиотека находится в проекте source/OdataEntity
Адаптер к контексту Entity Framework 6.1 source/OdataToEntity.Ef6
Адаптер к контексту Entity Framework Core source/OdataToEntity.Ef6Core
Адаптер к контексту Linq2Db source/OdataToEntity.Linq2Db
Клиент Microsoft.OData.Client для asp.net сервиса source/OdataToEntity.AspClient
Тесты Entity Framework Core source/OdataToEntity.Test
Тесты Linq2Db source/OdataToEntity.Test.Linq2Db
Пример клиента Microsoft.OData.Client и сервера WCF source/OdataToEntity.Wcf
Пример ASP.Net Core сервиса source/OdataToEntityCore.Asp


Скрипт создания базы Sql Server для тестов Linq2Db test\OdataToEntity.Test.Linq2DbModel\script.sql


→ Исходный код
→ Nuget пакеты

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

© Habrahabr.ru