Комментарии 66
Спасибо, попробуем.
+1
Очень интересно было бы услышать, про генерацию скрипта для создания структуры БД. Ну и вдвойне интересней с примерами генерации под разные СУБД.
if (book == book1) { Console.WriteLine(«Yep!!!»); }
чтобы так делать, нужно в классе Book перегрузить оператор ==.
чтобы так делать, нужно в классе Book перегрузить оператор ==.
NHibernate при работе с классами создаёт proxy объекты, поэтому необходимо все свойства делать виртуальными!
Я несколько раз по началу попадал на эти грабли:)
Я несколько раз по началу попадал на эти грабли:)
Вот если бы еще кто подсказал как здесь нормально оформить код. Сделал все по инструкции, а код не подсвечивает. %)
Всё просто: идёте сюда (http://source.virtser.net/default.aspx), вставляете свой код, на выходе получаете подсвеченный код нужного языка.
хм. да вы так и сделали:) Может быть теги ещё нельзя использовать вам?
Попробуйте отредактировать топик, у вас сейчас достаточно кармы, всё должно работать.
NHibernate — отличная ORM и вообще инструментарий для DAL-уровня (Data Access Layer). Однако, мы предпочитаем использовать ADO.NET Entity Framework для подобных дел. А для некоторых проектов — SubSonic. В принципе, все инструменты — отличные. Даже удивительно, но не видел откровенно плохих ORM для .NET — даже у LINQ to SQL вся проблема только в том, что он только для SQL Server, но очень просто и удобен в использовании.
одновременно блин)
Есть же Linq провайдеры для MySql, Oracle и PostgreSQL, например здесь (http://code2code.net/Db_Linq/).
Ну эт то я в курсе. Я говорил конкретно про реализацию LINQ to SQL, т.е. отдельно очень проработанный для SQL Server. Просто это, в отличие от других, нативная технология.
А так, мы используем или использовали в свое время и LINQ to Active Directory, и LINQ to NHibernate, LINQ to MySQL и даже писали свои провайдеры, реализующие интерфейс IQueriable, позволяющий обращаться к объектам-экземплярам с помощью LINQ.
А так, мы используем или использовали в свое время и LINQ to Active Directory, и LINQ to NHibernate, LINQ to MySQL и даже писали свои провайдеры, реализующие интерфейс IQueriable, позволяющий обращаться к объектам-экземплярам с помощью LINQ.
Я использовал DataObjects.Net на продакшене, всё рулило :)
я тоже сталкивался с этой библиотекой. единственный ее самый ощутимый минус — это убогая документация. я не про очевидные вещи конечно. да и на форуме их задаешь вопрос и потом месяц ждешь ответа. все-таки комьюнити у гибернейта побольше будет и своевременно можно получить ответ ;)
полезно,
хотя сейчас, после выхода vs sp1 и net 3.5 sp1 имхо интереснее сконцентрироваться на изучении нативных технологий, в смысле Entity Framework
хотя сейчас, после выхода vs sp1 и net 3.5 sp1 имхо интереснее сконцентрироваться на изучении нативных технологий, в смысле Entity Framework
не забудьте про nhibernate.attributes упомянуть. мне например удобно, когда все в одном месте. главное — не забывать order выставлять для них :)
CodeSmith сам не содержит никаких шаблонов, а является только инструментом для кодогенерации. А вот к нему много разных шаблонов, по которым можно генерить и DAL, и целые фреймворки (например, nettiers.com/ — .netTiers Application Framework).
Добавлю свою копеечку:
При использовании ORM библиотек необходимо проводить тестирование производительности на ранних этапах разработки.
Практически все ORM библиотеки грешат тем, что теряется контроль того, какие запросы они выполняют, а это может привести тормозам.
На небольших проектах это не критично, но вот если проект большой, я предпочту, чтобы Data Access Layer был максимально прозрачным (это упростит последующую поддержку и ловлю багов).
В последних нескольких проектах использую BlToolkit — очень нравится, но это не ORM.
При использовании ORM библиотек необходимо проводить тестирование производительности на ранних этапах разработки.
Практически все ORM библиотеки грешат тем, что теряется контроль того, какие запросы они выполняют, а это может привести тормозам.
На небольших проектах это не критично, но вот если проект большой, я предпочту, чтобы Data Access Layer был максимально прозрачным (это упростит последующую поддержку и ловлю багов).
В последних нескольких проектах использую BlToolkit — очень нравится, но это не ORM.
NHibernate очень любит увлекаться кэшированием. В определенных задачах это конечно плюс, но иногда кроме диких тормозов это ничего не дает. Особенно при большом объеме данных и крупных выборках, которые регулярно встречаются при построении отчетов.
Иногда приходится скрипя зубами отвергать удобный функционал NHibernate и грузить огромные коллекции в память и работать с ними уже там.
Вобщем не забываем чистить кэш и оценивать количество запросов к базе которое ORM генерирует.
Иногда приходится скрипя зубами отвергать удобный функционал NHibernate и грузить огромные коллекции в память и работать с ними уже там.
Вобщем не забываем чистить кэш и оценивать количество запросов к базе которое ORM генерирует.
вообще, что касается отчетов, то мне кажется такие задачи все-таки не входят в круг решаемых ORM. Отчет это табличные данные а их удобнее обрабатывать на стороне сервера БД в хранимках например. А NHibernate умеет работать и с хранимками.
Абсолютно согласен. Это как пример того что ORM — не панацея, как может показаться новичкам, впервые освоившим его.
Кроме того огромный плюс Hibernate — это возможность управлять структурой хранения данных и спокойно работать с ними напрямую. С ужасом вспоминаю Bold и ECO — то что они генерят, без поллитра не разобрать. И хранимок там уже не наваяешь.
Кроме того огромный плюс Hibernate — это возможность управлять структурой хранения данных и спокойно работать с ними напрямую. С ужасом вспоминаю Bold и ECO — то что они генерят, без поллитра не разобрать. И хранимок там уже не наваяешь.
Есть такое. Но все-таки большинство прикладных задач решаются именно с использованием ORM. Кстати, с LINQ to SQL и Entity Framework удобно работать с хранимками — они считают их по умолчанию методами модели приложения.
Мне интересно, есть ли отличия NHibernate от обычного Hibernate, который в Java?
Есть. NHibernate 1.2.1, о котором идет речь в статье, — это портированный джавовый Hibernate 2.1, Сейчас уже есть NHibernate 2 beta, который соответствует Hibernate 3.2. А последняя рабочая версия Hibernate — 3.3.0.0, т.е. сначала разрабатывается Java версия, и уже после этого все вкусности портируются под .NET.
Во всем остальном — различия только в синтаксисе ;).
Во всем остальном — различия только в синтаксисе ;).
В чём премущество NHibernate перед LinqToSQL?
Если посмотреть несколькими постами выше, то можно увидеть один из недостатков LINQtoSQL, то что он дружит только с SQL Server. Да и вроде как это не совсем ORM. Из преимуществ NHibernate то, что он более зрелый и обкатанный.
В «+» LINQ можно записать, то что он компилируется и то что он более «родной» для .Net'a.
В «+» LINQ можно записать, то что он компилируется и то что он более «родной» для .Net'a.
разработчики NHibernate уже заявили о реализации LINQ провайдера для своего детища. Так что скоро запросы в NHibernate тоже можно будет конструировать с помощью LINQ и этот плюс уже не будет таким уж плюсом ;)
Ну о том, как это сделать, уже достаточно давно написано, и это, кстати, одна из первых вещей, которую мы сделали, когда потребовалось использовать NHibernate в проекте.
Сам по себе LinqToSQL является больше даже не ORM-библиотекой, а удобным способом работы с данными. Причем только с данными MS SQL Server. Сравнивать было бы корректнее Entity Framework с NHibernate.
В LinqToSQL можно связать одну таблицу с одним классом в нашей модели. Этого достаточно в более простых приложениях, но при сложных структурах данных в это можно упереться.
LinqToSQL не поддерживает связи в базе данных Many to Many. Нужно самому это как-то реализовывать.
Классы, генерируемые LinqToSQL в основном выступают просто хранилищем, структурами. Внедрить в них бизнес-логику по обработке данных и взаимодействию друг с другом достаточно проблемно.
Это как основные недостатки (если это можно назвать недостатками, просто концепции разные) LinqToSQL в сравнении с другими библиотеками. По отличиям может рассказать автор топика, что может делать NHibernate по сравнению с linq.
В LinqToSQL можно связать одну таблицу с одним классом в нашей модели. Этого достаточно в более простых приложениях, но при сложных структурах данных в это можно упереться.
LinqToSQL не поддерживает связи в базе данных Many to Many. Нужно самому это как-то реализовывать.
Классы, генерируемые LinqToSQL в основном выступают просто хранилищем, структурами. Внедрить в них бизнес-логику по обработке данных и взаимодействию друг с другом достаточно проблемно.
Это как основные недостатки (если это можно назвать недостатками, просто концепции разные) LinqToSQL в сравнении с другими библиотеками. По отличиям может рассказать автор топика, что может делать NHibernate по сравнению с linq.
>В LinqToSQL можно связать одну таблицу с одним классом в нашей модели. Этого достаточно в более простых приложениях, но при сложных структурах данных в это можно упереться.
Да, тут согласен полностью. «Упереться» — немного не то слово, но неудобно: начинаются врапперы и т.д… Хотя, ИМХО, что писать враппер, что сидеть XML строчить… Первое, я бы сказал, гораздо лучше.
>Классы, генерируемые LinqToSQL в основном выступают просто хранилищем, структурами. Внедрить в них бизнес-логику по обработке данных и взаимодействию друг с другом достаточно проблемно.
Аналогично написанному выше.
>LinqToSQL не поддерживает связи в базе данных Many to Many. Нужно самому это как-то реализовывать.
Он реализовывает это так же, как это реализовано в БД — через промежуточный класс/таблицу.
В общем, ИМХО, что в лоб, что по лбу…
Да, тут согласен полностью. «Упереться» — немного не то слово, но неудобно: начинаются врапперы и т.д… Хотя, ИМХО, что писать враппер, что сидеть XML строчить… Первое, я бы сказал, гораздо лучше.
>Классы, генерируемые LinqToSQL в основном выступают просто хранилищем, структурами. Внедрить в них бизнес-логику по обработке данных и взаимодействию друг с другом достаточно проблемно.
Аналогично написанному выше.
>LinqToSQL не поддерживает связи в базе данных Many to Many. Нужно самому это как-то реализовывать.
Он реализовывает это так же, как это реализовано в БД — через промежуточный класс/таблицу.
В общем, ИМХО, что в лоб, что по лбу…
Ну почему же. Логика по валидации вполне себе встраивается и нормально живет, используя возможности partial-классов. То же самое, кстати, касается и Entities в ADO.NET Entity Framework.
А в целом LINQ to SQL еще развиваться и развиваться. Согласен, это не совсем ORM. Еще не слишком просто юнит-тестировать контекст данных LINQ (DataContext). Приходится создавать «test-specific fake data-context».
Насчет Many-2-Many согласен с предыдущим комментатором вашего комментария — как и в БД, это реализуется через дополнительную таблицу, которая, соответвенно, в свою очередь переходит и в класс LINQ2SQL.
А в целом LINQ to SQL еще развиваться и развиваться. Согласен, это не совсем ORM. Еще не слишком просто юнит-тестировать контекст данных LINQ (DataContext). Приходится создавать «test-specific fake data-context».
Насчет Many-2-Many согласен с предыдущим комментатором вашего комментария — как и в БД, это реализуется через дополнительную таблицу, которая, соответвенно, в свою очередь переходит и в класс LINQ2SQL.
Не знаю насколько будет дальше развиваться LinqToSQL как ORM система. EF не зря ведь писали :)
Связь ManyToMany, понятное дело, можно реализовать, но работа с ней уже не такой прозрачной будет, как с OneToMany, например. В этом как раз и недостаток я вижу. Мы не можем работать со связанными объектами как со «взрослыми» объектами, которые сами понимают что к чему. А так нужно ещё, с точки зрения логики, применять совсем лишнюю третью таблицу, которая с одной стороны как сущность, с другой стороны совершенно лишняя.
Хотя, если поизвращаться, то и к LinqToSQL тоже можно прикрутить связь ManyToMany.
Связь ManyToMany, понятное дело, можно реализовать, но работа с ней уже не такой прозрачной будет, как с OneToMany, например. В этом как раз и недостаток я вижу. Мы не можем работать со связанными объектами как со «взрослыми» объектами, которые сами понимают что к чему. А так нужно ещё, с точки зрения логики, применять совсем лишнюю третью таблицу, которая с одной стороны как сущность, с другой стороны совершенно лишняя.
Хотя, если поизвращаться, то и к LinqToSQL тоже можно прикрутить связь ManyToMany.
Ну с этим согласен, конечно! Концептуально, связь многие-ко-многим не должна быть сущностью. Это объект, описывающий отношение сущностей, в то время как в реляционной среде — это такая же «таблица», как и другие.
Поэтому, как раз, думаю, заморачиваться и извращаться не нужно, и там, где это оправдано — использовать Entity Framework, что мы, собственно успешно и делаем :) Действительно, не зря его разрабатывают.
Насчет сомнения по поводу LINQ to SQL, кстати — есть мнение, что это что-то вроде временного решения до появления EF, хотя и разрабатываются разными командами.
Поэтому, как раз, думаю, заморачиваться и извращаться не нужно, и там, где это оправдано — использовать Entity Framework, что мы, собственно успешно и делаем :) Действительно, не зря его разрабатывают.
Насчет сомнения по поводу LINQ to SQL, кстати — есть мнение, что это что-то вроде временного решения до появления EF, хотя и разрабатываются разными командами.
для меня основное преимущество — возможность работать на 1.1, 2.0 платформах
NHibernate нужно сравнивать скорее не с LINQ to SQL, а с другой разработкой от MS — ADO.NET Entity Framework.
расскажите потом как-нить, пожалуйста, с какими проблемами и недостатками ORM столкнулись в разработке
Ответил выше:
habrahabr.ru/blogs/net/37984/#comment_899304
habrahabr.ru/blogs/net/37984/#comment_899304
На данный момент, весь мой опыт работы с данными складывается из использования разнообразных ORM и лучшим решением (это, замечу, мое субъективное мнение) является на данный момент XPO от DeveloperExpress, следом за ним следует NHibernate затем SubSonik и LinqToSql. Одной из причин, по которой LinqToSql не может обойти конкурентов, является то, что он не умеет обновлять структуру базы данных, если в класс вносятся какие-либо изменения, приходится сносить базу и запускать создание по новой схеме. Вопрос решается сторонними примочками, но… это уже как-то некрасиво, на мой взгляд — это одно из первых умений, коим должен обладать ORM. Так что, XPO пока рулит. В плане же удобства использования ORM в сложных структурах — так мы их только потому и используем, что управлять объектами гораздо проще, чем копаться в SQL или чистом ADO.
NHibernate тоже не умеет обновлять базу, но это и логично, с учетом того сколько различных СУБД он поддерживает.
Для Firebird/Interbase я делаю проще. Обновление состоит из 3-х этапов:
1. Генерится новая временная база.
2. При помощи библиотеки из IBExpert метаданные сравниваются с метаданными основной базы и генерируется скрипт обновления.
3. Скрипт запускается на основной базе.
Естественно не все изменения можно применить, особенно если сильно меняется ссылочная структура, так что менять надо очень вдумчиво и внимательно, хотя это не излишне на всех этапах.
Для Firebird/Interbase я делаю проще. Обновление состоит из 3-х этапов:
1. Генерится новая временная база.
2. При помощи библиотеки из IBExpert метаданные сравниваются с метаданными основной базы и генерируется скрипт обновления.
3. Скрипт запускается на основной базе.
Естественно не все изменения можно применить, особенно если сильно меняется ссылочная структура, так что менять надо очень вдумчиво и внимательно, хотя это не излишне на всех этапах.
а еще есть CastleProject ActiveRecord — надстройка над NHibernate, которая полностью избавляет от XML и позволяет все модели описать в коде с помощью аннотаций C#, унаследовав модели от ActiveRecordBase. Там же обеспечивается сохранение сущностей и загрузка их. При этом ActiveRecord не скрывает от пользователя сам NHibernate, давая доступ к сессиям и прочим хитростям NHibernate. Выполнена в полном соответсвии с ActiveRecord паттерном. Сам использовал в одном проекте и вполне доволен.
От написания XML также избавляет NHibernate.Mapping.Attributes — стандартное дополнение к NHibernate.
Пример использования аттрибутов:
А за наводку на ActiveRecords — спасибо, покопаем.
Пример использования аттрибутов:
namespace BuisinessLayer.Directories
{
[Serializable]
[JoinedSubclass(NameType = typeof(Country), Table = «Countries», ExtendsType = typeof(PersistentObject), Lazy = true)]
public class Country: BuisinessLayer.PersistentObject
{
[Key(Column = «Id»)]
private string _nameRus;
private string _ISOCode;
[Property(Name = «NameRus», Length = 80)]
public virtual string NameRus
{
get { return _nameRus; }
set { _nameRus = value; }
}
[Property(Name = «ISOCode», Length = 3)]
public virtual string ISOCode
{
get { return _ISOCode; }
set { _ISOCode = value; }
}
}
}
* This source code was highlighted with Source Code Highlighter.
А за наводку на ActiveRecords — спасибо, покопаем.
По поводу супер-грамотно реализованного паттерна ActiveRecord в ORM — очень рекомендую посмотреть SubSonic.
на тему сравнения различных ORM для .Net можно еще почитать здесь: yuryskaletskiy.blogspot.com/2008/07/net-orm.html
Тыкал я его, серавно гавно по сравнению с простотой db40
Те же маппинг-файлы…
Гемор короче.
Опять же в любом ORM`е пример для даунов прекрасно работает, а вот как там сделать вложенные коллекции, да так, чтобы по разному грузились? В java`вском hibernate пробовал читать, но недопонял — наверное позже придется все-таки его ковырять.
А так моя ближайшая мечта — db40 или что-то подобное, тока когда оно станет похоже на правду, чтобы можно было под нагрузкой посмотреть.
Те же маппинг-файлы…
Гемор короче.
Опять же в любом ORM`е пример для даунов прекрасно работает, а вот как там сделать вложенные коллекции, да так, чтобы по разному грузились? В java`вском hibernate пробовал читать, но недопонял — наверное позже придется все-таки его ковырять.
А так моя ближайшая мечта — db40 или что-то подобное, тока когда оно станет похоже на правду, чтобы можно было под нагрузкой посмотреть.
ну зачем же гадости сразу? я же не кричу что NHibernate — это круто, а все остальное г***. Идеальных технологий и решений не бывает. да и если лопату брать не стого конца, думаю, копать будет очень трудно.
Я про ORM`ы в-принципе.
2trix: Вот это вот и прискорбно, что мы вынуждены сидеть на sql`е, коего плюс только в том, что он не дерево, а таблица.
А я человек и хочу мыслить как буратино — деревьями и графами*!
____________________________________________
* Как деревья хранить в SQL в курсе, здесь я о другом
2trix: Вот это вот и прискорбно, что мы вынуждены сидеть на sql`е, коего плюс только в том, что он не дерево, а таблица.
А я человек и хочу мыслить как буратино — деревьями и графами*!
____________________________________________
* Как деревья хранить в SQL в курсе, здесь я о другом
пока не видно предпосылок к тому, чтобы объектные базы были сравнимы по эффективности с реляционными. так что db4o — удел приложений с небольшой встроенной базой.
а если помнить о портабельности и удобстве администрирования, то окажется что для встроенной базы лучше использовать что-то типа hsql
а если помнить о портабельности и удобстве администрирования, то окажется что для встроенной базы лучше использовать что-то типа hsql
Как я понимаю — для CRUD будет генерироваться SQL запрос. А кодогенерация при активной нагрузке будет активно вымывать КЕШ БД. За что в больших корпоративных системах могут просто расстрелять
я пока не считаю себя гуру NHibernate, но насколько я знаю, генерация будет только при первом обращении, а потом все будет хранится в кэше, так что проблем с этим быть не должно.
Хм. Похоже не совсем корректно высказался.
Рассмотрим пример запроса через NHibernate, например, на чтение одной записи по ID.
Select [… fields...] from TABLE WHERE id='некоторое число'
Соответственно данное значение будет подставляться при кодогенерации и мы получим
Select [… fields...] from TABLE WHERE id='1'
…
Select [… fields...] from TABLE WHERE id='5'
…
Select [… fields...] from TABLE WHERE id='15'
Именно генерация sql строк и приведет к вымыванию из кеша БД закешированных запросов.
Рассмотрим пример запроса через NHibernate, например, на чтение одной записи по ID.
Select [… fields...] from TABLE WHERE id='некоторое число'
Соответственно данное значение будет подставляться при кодогенерации и мы получим
Select [… fields...] from TABLE WHERE id='1'
…
Select [… fields...] from TABLE WHERE id='5'
…
Select [… fields...] from TABLE WHERE id='15'
Именно генерация sql строк и приведет к вымыванию из кеша БД закешированных запросов.
>>В проекте предполагалось использование БД — исправьте
Я вот тоже решил осовить для себя orm, и ваши статьи мне очень помогают в расширении кругозора. Опять же встал вопрос выбора. EF ждать еще долго, и из существующих NHibirnate выглядит очень привлекательно. Не подскажите только где можно почитать (или может сами поделитесь?) про отличия (преимущества/недостатки) в сравнении с strongly typed datasets.
А где следующие части?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Основы NHibernate. Часть 1