Pull to refresh

Entity Framework или почему я реализую Repository

Reading time4 min
Views21K
Абстракции? Кому нужны абстракции?
EF наикрутейшая ORM от MS. habrahabr.ru/post/157267 это действительно круто. Разработать такую систему очень затратно по всем направлениям. CodeFirs вещь, знания проектирования БД, да какой там! Не нужны сами знания SQL – и это круто. Но так ли все радужно?
Julie Lerman может много рассказать msdn.microsoft.com/en-us/magazine/ff898427.aspx
image
Ничего не напоминает?
Это реализация Repository + UoW. Так значит, при использовании EF делать всевозможные обертки бесполезно?
EF безумно популярная технология, не найти нужного провайдера под свое хранилище затруднительно.
Основная идея EF ( как и любого Repository ) – отделение предметного слоя от слоя хранения. Но зачем?
Все просто – что бы без болезненно изменять хранилище и предметку не зависимо.
Когда нужно менять хранилище?

Хотелось бы что бы никогда, но как говориться «никогда не говори..». Я работаю над проектом, в котором два боевых слоя хранилища и еще одно демонстрационное. Клиент сам выбирает, как он будет хранить свои данные.
Нужно ли строить абстракцию поверх абстракции и делать то, что уже и так реализовано?

Ответ лежит в совместимости конкретных провайдеров. Вот что о совместимости говорит один из разработчиков таких провайдеров Yevhen Shchyholyev www.infoq.com/articles/multiple-databases. Проблемы которые были понятны на интуитивном уровне укрепляются самими разработчиками.
Вот некоторые из них

Типы данных


Entity Framework поддерживает ограниченный набор .NET типов (signed integers, Single, Double, Decimal, String, Byte[], TimeSpan, DateTime, DateTimeOffset, Boolean, Guid). Однако не все.NET типы из этого списка поддерживаются базами данных.

Типы – вечная проблема. То есть один сценарий, выполненный на одном провайдере ( именно на провайдере ) может не дать тех же результатов на другом.
Поддержка DateTimeOffset

DataTimeOffset — самый проблематичный тип.NET. Он поддерживается в SQL Server MS 2008, Oracle и SQLite, но не в SQL Server MS 2005, MySQL или PostgreSQL, так как в этих базах данных отсутствует DateTime, который может сохранить смещение часового пояса.

Проблема возникшая у нас, дата храниться в UTC, но EF под SQLight упорно возвращал в Local. Проблема легко была решена, тк мы используем Mapping.
Производительность

Если специфические особенности определенной базы данных не приняты во внимание, возможно, что LINQ-запрос может быть обработан быстрее в одной базе данных и медленнее в другой.
Разбивка на страницы данных, выполненная LINQ-методы .Skip ()/.Take(), может быть одной из самых затратных операций. В отличие от в SQL Server, Skip /Take, Oracle, генерирует два подзапроса с сортировкой во внутреннем подзапросе, который может негативно повлиять на производительность. Нужно отметить, что разбивка на страницы может быть довольно неэффективной в других базах данных, особенно если сортировка выполнена по неиндексируемыми столбцами.

Вот тут самое интересное, под разные провайдеры нужно писать свои запросы на LINQ. Еще интересный сценарий: написали некоторый функционал с кучей запросов к контексту и все прекрасно работает. Но приложение cross и нужно проверить, как это все будет работать на другом провайдере. Было обнаружено, что часть запросов стали не эффективные. Не беда – оптимизация. Все хорошо. Вопрос как оптимизация отразилась на работе при исходном провайдере?
Ограничения запроса

В EF разработчик может сформировать запросы, используя или LINQ to Entities, или Entity SQL или их комбинацию. В любом случае такой запрос преобразовывается механизмом EF в промежуточное представление как expression tree и отправляется в EF-провайдер, чтобы он сгенерировал SQL запрос. Так как EF была первоначально разработана для SQL Server, то иногда EF-провайдеры должны значительно преобразовать первоначальное expression tree, чтобы сгенерировать корректный SQL для определенной базы данных. Однако это не всегда возможно.

Здесь ясно сказано mission impossible. SQL SQLю рознь, провайдер провайдеру. Тут даже речь не о том, что запрос будет не эффективен, а о том, что он может покрошить выполнение приложения.
Соответствующий раздел MSDN говорит, что все эти функции поддерживаются всеми EF-провайдерами:
«В этом разделе рассматриваются канонические функции, которые поддерживаются всеми провайдерами данных и могут использоваться всеми технологиями запросов».
Этот раздел, кажется, сверхоптимистичен, поскольку различные DBMS обладают различной функциональностью, и иногда невозможно реализовать все возможности для совместимости.

Вот ссылка. Но не абы кто, а ведущий разработчик набора сторонних провайдеров говорит mission impossible.
Заключение

В этой статье я попытался предоставить краткое описание наиболее распространенных проблем в процессе разработки EF-приложений для не Microsoft SQL Server баз данных. Несомненно, много других аспектов не получили внимания в этой статье...

То есть это не все проблемы какие могут возникнуть по мимо описанных, и о каких можно узнать только встав на грабли.

Подводя итоги.


EF это хорошая абстракция, и как любая абстракция, она не лишена главного недостатка – ее реализации. Проблемы описанные в этой статье взяты не из головы и не из уст скептиков, а из первых рук – разработчика провайдеров.
Провайдеры разрабатываются разными фирмами и я уверен, что если в одном проекте использовать провайдеры от разных производителей проблем с совместимостью будет гораздо больше. forums.mysql.com/read.php?174,614148,614148
Я ни в коем случае не говорю НЕТ EF, я говорю да Repository, ведь все описанные проблемы легко обойти с помощью этой абстракции которая обернет EF и поглотит проблемы совместимости.

P. S.


Рассмотрен лишь технологический пример для чего может понадобиться реализовывать «Велосипед», причин по которым можно и нужно использовать репозиторий и примочки гораздо больше.
Tags:
Hubs:
+1
Comments269

Articles

Change theme settings