ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)

Preview:

DESCRIPTION

Расскажу зачем они вообще нужны. Пройдемся по технологиям и промоем им косточки. Рассмотрим достоинства и недостатки, а также где и когда лучше всего применять ту или иную ORM.

Citation preview

ORM

Цуканов Павелptsukanov@codereign.netSkype: cpp.tula

На примерах NHibernate, Entity Framework, LINQ to SQL

ORM это• Object Relational Mapping =

Объектно-ориентированная проекция (отображение)

• А если проще. Это возможность без больших затрат сохранять/считывать объекты в базе данных

Что было до ORM

Что стало после

А зачем это надо• Меньше кода.

• Нет небходимости самому писать SQL запросы.

• Нет необходимости самому создавать объекты.

• Можно работать с имеющимся доменными/бизнес объектами.

• В конечном итоге это проще сопровождать.

5 причин использовать ORM

• Сокращает время разработки.

• Позволяет создать более лучший код.

• Нет необходимости быть экспертом .NET, что-бы использовать ORM.

• Сокращает время тестирования.

• Упрощает сопровождение.

Сокращает время разработки

• Сокращает вам кучу времени на разработку от 20% до 50% (в зависимости от проектов).

• Типично для 15-20 таблиц это 30-50 объектов, а это примерно от 5000 до 10000 строк кода. И это надо написать и протестировать.

• С ORM тоже можно сделать за 1-2 дня. Причём основное время потребуется на обдумывание как осуществить маппирование корректно.

Позволяет создать более лучший код.

• Разные люди в команде могут создать свой уникальный код для преобразования объектов из/в БД, опираясь исключительно на свой опыт.

• ORM использует шаблоны кода, которые имеют отличный дизайн. Причем, эти шаблоны кода почти всегда следуют известным шаблонам проектирования. Таким образом, код, который вы будете получать от ORM очень вероятно, будет лучше разработаны, чем код, разработанный собственной командой.

Нет необходимости быть экспертом .NET, что-бы использовать ORM.

• Вы можете начать использовать ORM очень быстро имея лишь поверхностные знания.

• Удивительно, но это факт, подчеркнутый из собственного опыта.

• При этом ваш код не будет сильно отличаться от экспертов в этом вопросе.

• Хотя конечно, есть и подводные камни.

Сокращает время тестирования.

• Вам нет необходимости вручную преобразовывать объекты из/в базу данных. А следовательно нет необходимости тестировать того чего нет.

• Код который делает такое преобразование написан за вас и уже протестирован.

Упрощает сопровождение.

• Жизнь программы не заканчивается выпуском релиза. Она живёт и развивается и изменение кода в случае с ORM менее затратное занятие. Так как вы написали меньше кода

• Разработчик знающий как функционирует та или иная ORM может без проблем переключится с проекта на проект и понять как тут всё устроено.

Что у нас есть• LINQ to SQL (

http://msdn.microsoft.com/en-en/library/bb386976.aspx)

• Entity Framework (http://msdn.microsoft.com/en-en/library/bb399572.aspx)

• Nhibernate (http://nhforge.org)

• eXpressPersistent Objects™ (http://www.devexpress.com/products/NET/XPO)

• LLBLGen Pro (http://www.llblgen.com)

• Dapper.NET (http://code.google.com/p/dapper-dot-net/)(ORM сайта StackOverflow).

• И т.д.

LINQ to SQL

• Входит в состав .Net Framework начиная с 3.5.

• Разработано спецально для работы с MSSQL сервером через LINQ.

• Отказано в развитии.

Entity Framework

• Входит в состав .Net Framework начиная с 3.5

• С .Net Framework 4.0 это рекомендуемый способ доступа к БД через Linq

• Последняя версия 5.0 находится в бетта версии и будет доступна с .Net Framework 4.5

• ORM-решение для платформы Microsoft .NET портированное с Java.

• Бесплатная библиотека модно найти на http://nhforge.org

• Последняя версия 3.2

Сравним

Сложность

• LINQ to SQL – Самая лёгкая и простая

• Entity Framework – Более сложная. Визуальный интерфейс позволяет сделать сложные вещи очень просто.

• NHibernate – Наиболее продвинутая ORM из вышеперечисленных

1

Наследование

• LINQ to SQL – Table per Class Hierarchy (TPH).

• Entity Framework – несколько видов наследования Table per Class Hierarchy (TPH), Table per Type (TPT), and Table per Concrete Class (TPC).

• NHibernate – дополнительно к NHibernate - Implicit polymorphism

2

TPH (Table per Class Hierarchy )

TPT (Table per Type)

TPC (Table per Concrete Class)

Implicit polymorphism

public static List<Object> GetAll() { List<Object> objects = session.find(“from Object”); return objects;}

Поддержка БД

• LINQ to SQL – MSSQL2000 и старше.

• Entity Framework – MSSQL, IBM DB2, Sybase SqlAnywhere, Oracle, SQL Azure и многие другие. Главное чтобы был ADO.Net Data provider для соответствующей БД.

• NHibernate – Microsoft SQL Server 2005/2000, Oracle, Microsoft Access, Firebird, PostgreSQL, DB2 UDB, MySQL, SQLite. Определяется наличием соответствующего драйвера у NHibernate.

3

Сложность разработки

• LINQ to SQL – прост в обучении и при разработке простых приложений.

• Entity Framework – более сложная библиотека и требует время на изучение всех ньюансов. Рекомендуется как для простых так и сложных приложений.

• NHibernate – Достаточно сложная в изучении чем Entity Framework. Однако гибкость конфигурирования позволяет легко сопровождать приложения. Рекомендую для сложных проектов.

4

Типы используемых файлов

• LINQ to SQL – файл DBML – содержит XML маппинг классов к таблицам

• Entity Framework – обычно EDMX файл генерируется во время разработки. Остальные CSDL, SSDL, MSL файлы во время компиляции.

• NHibernate – XML файлы конфигурации.

5

Поддержка комплексных типов

• LINQ to SQL – нет

• Entity Framework – да

• NHibernate – нет.

6

Поддержка LINQ

• LINQ to SQL – да. Основной способ работы с базой данных.

• Entity Framework – да. Основной способ работы с базой данных.

• NHibernate – да, но в ограниченном объёме (во всяком случае в NH 2.0).

7

Производительность

• Cчитается что как ни странно Entity Framework – быстрее чем LINQ to SQL.

• NHibernate – позволяет добиться более высокой производительности при более тонкой настройке.

8

Будущее библиотек

• LINQ to SQL – не развивается.

• Entity Framework – активно развивается и конечном итоге дожна заменить LINQ to SQL.

• NHibernate – развивается пока есть энтузиасты.

9

Генерация кода из БД и наоборот

• LINQ to SQL – генерирует классы из БД.

• Entity Framework – генерирует классы из БД и наоборот

• NHibernate – всё ручками.

10

Работа с POCO (Plain Old CLR Objects) объектами

• LINQ to SQL – работает, но с натяжкой.

• Entity Framework – да

• NHibernate – да.

11

Способы маппирования

• LINQ to SQL – через атрибуты.

• Entity Framework – через аттрибуты, XML файлы

• NHibernate – через аттрибуты, XML файлы, Fluent NHibernate.

12

Кэширование

• LINQ to SQL – Кэш 1-го уровня.

• Entity Framework – Кэш 1-го уровня. Кэш 2-го уровня через обертки (http://code.msdn.microsoft.com/EFProviderWrappers)

• NHibernate – Есть кэши 1-го и 2-го уровня.

13

Кэш 1-го уровня[Test]public void trying_to_get_the_same_account_a_second_........... (){

Console.WriteLine("------ now getting entity for the first time"); var acc1 = Session.Get<Account>(account.Id); Console.WriteLine("------ now getting entity for the second

time"); var acc2 = Session.Get<Account>(account.Id);  acc1.ShouldBeTheSameAs(acc2);

}

Без кэша 2-го уровня

[Test]public void trying_to_load_an_existing_item_twice_in_................. (){ using(var session = SessionFactory.OpenSession()) { var acc = session.Get<Account>(account.Id); acc.ShouldNotBeNull(); } using(var session = SessionFactory.OpenSession()) { var acc = session.Get<Account>(account.Id); acc.ShouldNotBeNull(); }}

Без кэша 2-го уровня

С кэшем 2-го уровня

[Test]public void when_updating_the_entity_then_2nd_level.......... (){ using(var session = SessionFactory.OpenSession()) using (var tx = session.BeginTransaction()) { var acc = session.Get<Account>(account.Id); acc.Credit(200m); tx.Commit(); } using(var session = SessionFactory.OpenSession()) { var acc = session.Get<Account>(account.Id); acc.Balance.ShouldEqual(1200m); }}

С кэшем 2-го уровня

Провайдеры кэша 2-го уровня

• Velocity: использует Microsoft Velocity (http://msdn.microsoft.com/en-us/data/cc655792.aspx)

• Prevalence: использует Bamboo.Prevalence (http://bbooprevalence.sourceforge.net/)

• SysCache: использует System.Web.Caching.Cache.

• SysCache2: подобно SysCache но с более продвинутуми настройками кэширования.

• MemCache: использует memcached (http://www.danga.com/memcached/).

• SharedCache: смотри (http://www.codeplex.com/SharedCache) и http://www.sharedcache.com/cms/

API

• LINQ to SQL и Entity Framework имеют менее богатый API чем NHibernate

• Например NHibernate имеет −Перехватчик запросов, вставки,

удаления и обновления−Перехватчик создания объекта−Логгирование с использованием

log4net.

14

Проблемы

• Скрытие БД ведёт к деградации производительности.

• Баги в библиотеке ведёт к нетривиальным методам решений.

• Иерархия классов может привести к блокировкам в БД и как следствие к деградации производительности.

• Загрузка классов, содержащие в полях экземпляры других (сохраняемых также через ORM) классов. Может привести к длительному процессу.

Заключение

• Каждый вправе выбирать ORM себе по вкусу. Так как нет универсального решения.

• Для маленьких проектов я бы предпочёл LINQ to SQL или Entity Framework.

• Для средних Entity Framework и NHibernate.

• Для больших только NHibernate.

Пожалуйста, Ваши Вопросы!!!