суббота, 4 апреля 2009 г.

.NET, NHibernate, Castle ActiveRecord и генераторы кода. В поисках истины

Я работал раньше с ORM’ами на других языках программирования, и должен сказать, что я, как человек ленивый и стремящейся всеми возможными способами упростить свою работу, уже прочно привык к их использованию. Так что, вместо того, чтобы писать деревянные и тривиальные запросы для CRUD-операций и кучу JOIN’ов для реализации связей между таблицами, я предпочитаю заюзать хороший ORM и не париться по этому поводу.
Так как проект пишется на ASP.NET с возможной поддержкой Mono, то мне было необходимо, чтобы этот ORM работал с MySQL, чтобы был хороший генератор кода для классов записей, и чтобы он был как можно проще для изучения. Ну, не хочу я месяц тратить на изучение какой-нибудь технологии, без которой, я в принципе, могу и обойтись.

NHibernate


Первое, что мне бросилось в глаза для .NET – это NHibernate (рус. http://nhibernate.ru/). Очень мощный ORM, используемый достаточно большим количеством людей. На то, чтобы разобраться в азах этой штуковины, я потратил целый вечер, и понял, что это вещица это действительно мощная, но не такая уж и простая и содержит кучу нюансов. Это я понял, пролистав «купленную» книгу NHibernate In Action и просмотрев несколько отрывков из скринкастов по NHibernate. Слишком сложно. В топку :(

ActiveRecord


Бороздя необъятные просторы Интернета, я все-таки нашел то, что мне нужно. Это Castle ActiveRecord. Хорошо, что он построен на базе NHibernate, так что мне не пройдется отказываться от функционала NHibernate. Но, это проще чем NHibernate! И это то, что нужно для моего проекта. Ура! Меня не пугает то, что последний релиз (точнее релиз кандидат) был полтора года назад, я смотрю на то, что в Сети есть много позитивных отзывов по поводу Castle ActiveRecord. Кроме того, я немного работал с ActiveRecord в Ruby, и уверен, что для меня не составит труда быстро изучить, как использовать реализацию ActiveRecord на C#.

Генераторы кода


Уйму времени потратил на то, чтобы найти тулзу, которая бы сгенерировала мне код для моих ActiveRecord классов. Ситуацию осложняло то, что мне нужно было сгенерировать классы, по готовой БД, под управлением MySQL. Перепробовал кучу генераторов кода, но одни отказывались работать с MySQL, другие отказывались работать с MySQL. Хотел уже впасть в панику, и перегнать БД из MySQL в SQL Server, и уже от туда сгенерировать нужные классы. Но, проблема разрешилась. Нашел вот это:
Caragen Tool - the Castle Active Record Autonomous GENerator tool, которое прекрасно поддерживает работу с MySQL.

И сейчас, довольный тем, что у меня есть готовые классы c уже описанными полями, пошел править связи между таблицами.

11 коммент.:

mind комментирует...

Да уж, реально объективное описание что лучше. По результатам одного вечера выбор пал на продукт полуторагодичной давности, да еще и с заплатами к генераторам кода. Это ерунда, что все есть в Хибере, главное ведь сделать что-то, не имеет значения как и будет ли работать.

DmytroZ комментирует...

mind, я так понимаю, что вы можете предложить лучший способ:
1. ORM получше, чтобы MySQL поддерживал, был не сложным для простых вещей
2. Чтобы код классов, которые мапят таблицы БД, генерировался автоматически
3. Чтобы оно под Mono работало (желательно)

Я для себя все это нашел в Castle ActiveRecord. Вчера подпилил связи, и принялся за реализацию бизнес логики. Если бы я использовал чистый NHibernate, я бы еще недельку читал туториалы.

>>Это ерунда, что все есть в Хибере, главное ведь сделать что-то, не имеет значения как и
>> будет ли работать.

Ну, конечно же, все должно работать. В Хибере всего нет. А где есть все? :)

mind комментирует...

Ну хорошо, по пунктам:
1. Поскольку Hibernate (для Java) стал чуть ли не прототипом спецификации EJB 3 (по меньшей мере, благодаря участию главного разработчика первого в разработке спецификации второго), да еще NHibernate есть портирование (уж не знаю ьыл ли взят хоть какой-либо код, но эо не столь важно) на .НЕТ платформу, той же компанией, могу с высокой степенью утверждать что функционала там немало. Касательно простых вещей - я не вижу проблемы добавить аннотации к десятку полей "простого" приложения.
2. Генерация кода, ни исходного Java или C#, ни конфигурации маппинга (в Java такое можно сделать отдельно от Java кода), не есть хорошо по причине явного несоответствия объектной модели Java/C# и реляционной. Для приличного приложения бывает думают об уникальности значений, индексах и внешних ключах. Если в базе все плохо, сгенерированный код будет еще хуже. Из опыта - не генерил код ни разу ввиду приведенных причин.
3. Mono - неподдерживаемый мелкомягкими проект, и даже более - в любой момент дело может обернуться судом. Я бы забыл о каком-либо портировании гейтсовских технологий на что-либо, о чем их инженеры не думали, или на что забили большой болт.

А туториалах умные вещи пишут. Я бы побоялся ездить на мишине, которая была собрана с мыслью что она "по идее должна ездить".
Чтобы утверждить "в хибере всего нет", стоит определиться что в нем есть, и что от нужно, чего в нем нет.
Все вышесказанное исключительно ИМХО, но к серъезным проектам с таким подходам не подпустил бы на расстояние выстрела.

DmytroZ комментирует...

>> 1. Поскольку Hibernate (для Java) стал чуть ли не прототипом спецификации EJB 3 (по
>> меньшей мере, благодаря участию главного разработчика первого в разработке
>> спецификации второго), да еще...

Да, Hibernate мощная библиотека, используемая сотнями программистов, именно поэтому я и присмотрелся к NHibernate с самого начала. Но, для того, чтобы использовать ORM эффективно, необходимо для начала ознакомится со всем его функционалом. Иначе, это очень пагубно отразится при создании кода приложения. Поэтому, чем «проще» ORM – тем лучше для меня, кроме того, как я уже говорил, я знаком с реализацией ActiveRecord на Ruby, и знаю, что от него ожидать. Кроме того, я всегда, при возникновении сложной проблемы, которую я не смогу решить при помощи ActiveRecord (пока что не представляю, что это за проблема может быть), смогу «спустится» на уровень NHibernate.

>> 2. Генерация кода, ни исходного Java или C#, ни конфигурации маппинга (в Java такое
>> можно сделать отдельно от Java кода), не есть хорошо по причине явного
>> несоответствия объектной модели Java/C# и реляционной...

Вроде бы Object/Relation Mapper’ы и призваны разрешить проблему между несоответствием объектной модели ЯП и реляционной моделью БД...

У меня в приложении около 20 таблиц, и приблизительно более 60-ти полей. Я, конечно же мог скопипастить имена полей из базы данных, преобразовать их в CamelCase, а потом подбавлять аннотации, но зачем? Я сэкономил себе кучу времени используя генератор кода. Конечно же, код пришлось немного подправить, внеся необходимые связи между таблицами, но зато я не допустил опечаток при копипастинге и наборе кода.

>> 3. Mono - неподдерживаемый мелкомягкими проект, и даже более - в любой момент
>> дело может обернуться судом. Я бы забыл о каком-либо портировании гейтсовских
>> технологий на что-либо, о чем их инженеры не думали, или на что забили большой
>> болт.

Да, слышал я про возможные суды, про патенты и т.д., по этому я говорю о желательной поддержки Mono. Их инженеры (Microsoft) хорошо все продумали, и поэтому сделали .NET платформой которая, теоретически может работать на разных ОС. А Mono доказывает, что это возможно и практически. Microsoft не будет поддерживать Mono сейчас, это нецелесообразно экономической точки зрения, им же ведь Винду нужно продавать ;). Но, с другой стороны, разработчики Mono продолжают работать, и выдавать новые релизы, видимо призрачный суд Novell не пугает :)

>> А туториалах умные вещи пишут. Я бы побоялся ездить на мишине, которая была
>> собрана с мыслью что она "по идее должна ездить".

Угу, мне тоже было бы страшно ездить на такой машине, поэтому я бы полез в Интернет узнать, как люди отзываются об этой машине, какие баги в ней есть и тому подобное. Если в туториале говорится, что машина по идее должна ездить, и она действительно едет, то почему бы не поездить? :)

>> Все вышесказанное исключительно ИМХО, но к серъезным проектам с таким
>> подходам не подпустил бы на расстояние выстрела.

По-моему, все-таки тема «такого подхода» недостаточно, раскрыта, если у вас будет желание, то мне было бы интересно почитать пост на эту тему в вашем блоге.

mind комментирует...

Я бы с радостью продолжил обсуждение проблемы, но не в своем блоге - я просто не обладаю талантом (а может не все так запущено :) ) чтобы писать о процессах, организации и тем более абстрактных вещах. Так сложилось, что мне интересны чисто технические вещи и крайности человеческой личности - название блога говорят сами за себя. Тут я на всякий уточню, что ни на что не намекаю, и к ИТ имеет такое же отнощение, как и ко всему остальному.

Unknown комментирует...

на codeplex появился Generator Studio
http://www.codeplex.com/generatorstudio

Генерит:)

по поводу дискуссии - какой смысл использовать орм, если надо все писать ручками - то же самое, что самописный DAL

Unknown комментирует...

А какая тулзятина может сгенерировать код для MS SQL?

DmytroZ комментирует...

Из всех просмотренных, мне понравился Nconstruct. Там есть бесплатная Lite версия:
http://www.nconstruct.com/
Очень крутые перцы используют CodeSmith, но он платный, хотя и с триальной версией, но я его честно признаться еще не смотрел:
http://www.codesmithtools.com/

Хотел попробовать MyGeneration, но, так и не понял что там нужно делать, он не очень юзабельный, а разбираться у меня не было времени.

Unknown комментирует...

Спасибо за ответ :)

Valik комментирует...

Дмитрий, а почему ты не рассматривал LINQ to Entities или LINQ to MySQL?

DmytroZ комментирует...

LINQ to MySQL я не доверяю. Сейчас использую Linq 2 SQL, пока что вполне хватает, соответственно под SQL Server.

Отправить комментарий

 

.NET ate my MOSK;. Powered By Blogger © 2009 Bombeli | Theme Design: ooruc