Entity Framework 7 + Redis

в 4:38, , рубрики: .net, entity framework, nosql, redis

Microsoft таки решили добавить в свой флагманский orm поддержку не реляционных хранилищ данных.
Лично я узнал об этом на teched europe 2014 (кто-то, возможно, знал и ранее).
В EF7 заявлена поддержка Redis и Azure Table Store.

image image

Table Store для тех, кто Azure не пользуется, не интересен в принципе.
А вот поддержка Redis — другое дело, т.к. in memory key-value store, которое можно держать на своих серверах — это уже интересно.

Все что написано ниже, относится к текущему состоянию код, которое далеко от завершения. Цитата из EF wiki:
"As you try out EF7 please bear in mind that this is a very early stage in the development of the new EF codebase and there are many features that are partially implemented or not yet available."

Вообще про EF7

EF7 использует (на 10 ноября 2014 года) библиотеку работы с Redis от StackExchange доступной на nuget.org
Это приятно, что MS не стал писать свою собственную библиотеку, хотя они и могли это сделать.
Пока EF7 не доступен в nuget (на 10 ноября 2014 года), но на github уже можно смотреть
(В видео с teched europe показывали ef7-pre, но на общем nuget его пока нет.)

EF7 пишется сразу, чтобы работать с VS2014(в vs2013 update2 тоже работает), с asp.net vnext (json файлы с зависимостями) и т.д.
У меня не получилось скомпилировать проект ни на vs2013, ни vs2014 т.к. не хватало части зависимостей сначала, а потом вылетела ошибка описанная тут до меня. Чтобы собрать проект, нужно прочитать инструкцию , но мне пока это не помогло.

В EF появится Fluent Api, которое специфично для провайдера (для Relation или для Azure Table Store). Наверное, и для Redis что-тоспецифичное появится, но про это информации в wiki нет.

На Teched Europe говорилось, что EF7 станет более расширяемым. Я не знаю, что было первичным: «расширяемость» или «поддержка key-value store», но последнее без первого все равно не возможно. Т.к. Генератор sql в redis точно не нужен, к примеру, как и миграции от code first.

Что можно сказать про Redis сейчас:

На EF Wiki есть статья "EF7 Redis provider" в которой есть хоть какая-то информация о работе с Redis, ограничениях по работе с ним.

Новых функций/методов/api для Redis учить особо не придется, если Вы ранее с EF уже работали.
Код выглядит примерно так же:

Создаем контекст, выбираем из него типизированный DbSet.
Работая с DbSet, можем делать все CRUD операции.

image
Для Redis также поддерживаются не только синхронные, но и асинхронные версии методов.

image
Из DbSet (Реализует IQuariable) все так же можно получить все нужные нам выборки, агрегации и т.д. (правда, реализованы они, понятное дело, отлично, от sql версии.)

image

Что самое приятное — многие тесты, общие для Redis версии и SQL server.
Например, тест на отключение ChangeTrackingManager

(способ ускорить работу, если нам не нужно отслеживать изменения в объектах).

image
С запросами с фильтрацией(where) данных надо быть очень аккуратными.

Когда мы будем искать что-то по ключу — все просто, выборка по ключу быстрая операция. Когда делается условие where то в реляционную базу отправлялся запрос и where проводилась на базе данных. В бд могли быть индексы и можно было получить быстрый результат, даже на большом объеме данных. В случаи Redis, будет сканирование всех значений, без каких либо индексов. Думаю на клиент выноситься это не будет, но поиск сканирование всех данных, однозначно медленнее поиска по индексу.

Чего нет и не будет?

В EF можно было вызвать Include, чтобы загрузить NavigationPropery. На базе при этом делался join таблицы по внешнему ключу.

В случаи Key-Value store никаких navigation property быть не может, т.к. relations отсутсвуют в key-value store и нет ни какогот join.

image
Database/Model First подхода тоже не должно быть.

  • Из InMemory Store вытащить модель данных и сгенерировать на основе классы не возможно. Каждая база данных имеет только номер, но не название. База данных- это не набор таблиц, таблиц не существует. Вопрос как при этом получить какие-то строготипизированные сущности в модели Database First? Ответ- только очень странными и не очевидными способами.
  • Model First ?- Model First может и хорошая идея, но базу из нее в нашем случаи не сгенерируешь, а рисовать модель, которую можно просто описать в коде достаточно трудозатратно. Да и кто-то ее на самом деле использовал?

Интересные вопросы:

В EF можно через context на прямую вызвать хранимку или произвольный sql код выполнить на mssql server.
В Redis встроен скриптовый движек Lua, хочется понять можно ли его через EF использовать.
Можно ли на прямую будет вызвать команды, если мы поймем, что генерируемый EF запрос не такой, как должен быть.
Наверное есть случаи, когда вызов кода Lua через EF был бы разумен, как и команд на прямую. В текущих документах есть информация по этому поводу, но очень размыто в разделе Query Sorting
«You can also use the same command to store the result in another data structure that a LUA script could then analyze.»

Что бы хотелось узнать:

Лично мне хотелось бы узнать 2 основные вещи:

  • Насколько % EF версия медленнее, чем обычная StackExchange версия. Понятно, что вопрос сложный и зависит от многих факторов, но хоть какие-то цифры увидеть бы.
  • Насколько стабильно работает с кластерной конфигурацией? Т.к. именно работа кластера таких серверов и интересует.

Вряд ли мы узнаем это в ближайшее время, ибо до выхода EF еще времени немало. Пока на nuget нет версий даже пакетов от ef7, а раньше перед релизом всегда появлялись всякие alpha,beta,rc.
Да и в записках архитектурных комитетов тоже не понятно

Выводы: будем внимательно следить за успехами команды EntityFramework. Может, когда-нибудь появится возможность и другие nosql базы использовать.

P.S.
В команде EF Иванов Иван Иванович не пользуется уважением.

В качестве имен используется персонажи из my little ponny...

image
image

Исходный текст статьи на github

Автор: SychevIgor

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js