Переписывание приложения NHibernate в Linq для SQL - PullRequest
4 голосов
/ 01 октября 2010

У меня есть старое устаревшее приложение, написанное с использованием NHibernate. Теперь я хотел бы переписать его, включая новый функционал и большие изменения в модели.

Каковы основные недостатки использования Linq для SQL вместо NHibernate?

Каковы возможные проблемы использования LINQ to SQL, делает ли DataContext чем-то вроде синглтона низкую производительность?

Ответы [ 6 ]

8 голосов
/ 01 октября 2010

С "Ложный миф инкапсуляции доступа к данным в DAL" :

«Я хотел бы спроектировать систему / приложение, используя NHibernate. Но я также хочу быть настолько гибким, что в будущем, если я отключу NHibernate и использовать фреймворк ADO.NET Entity или другой фреймворк приложение не должно аварийно завершить работу. "

Короче говоря, я полностью против даже пытаясь сделать что-то подобное.

Он основан на ошибочных предположениях

Многое за этим стоит основанный на историческом двигателе, построенном в время, когда слои доступа к данным прямой доступ к базе данных, используя его собственный диалект, что приводит к необходимости создать именно такую ​​инкапсуляцию в Для поддержки нескольких баз данных.

Проблема с этим диском в том, что он больше не фактор, все современное OR / Ms может обрабатывать несколько баз данных эффективно. Кроме того, современные OR / M являются больше не просто способы выполнить некоторые SQL и получить результат обратно, который как старый стиль DAL были написаны. OR / M берет на себя гораздо больше обязанности, от таких вещей, как отслеживание изменений для управления кешем, от обеспечения оптимистичного параллелизма управлять оптимальным общением с база данных.

И эти функции очень важны. Не только это, но они разные между каждым ИЛИ / М.

Это не работает, и вы узнаете об этом слишком поздно

Основная проблема в том, что как бы старайся, там будут тонкие и не очень тонкие различия между различными OR / Ms, эти изменения может кардинально повлиять на то, как вы строите ваше заявление.

Так как вы перемещаетесь между OR / Ms?

Есть причины, по которым некоторые люди хотят перейти от одной технологии доступа к данным к другой. Я участвовал в нескольких таких усилиях, и подход, который мы использовали в каждом из этих случаев, заключался в портировании , вместо того, чтобы пытаться отбросить новую реализацию IDataAccess.

3 голосов
/ 01 октября 2010

Огромный вопрос, но одна вещь, о которой я узнал во время большого рефакторинга из L2S в NHibernate 2.x, заключается в том, что NHibernate позволяет представлять базовый класс в другой физической таблице, чем производная.Но в L2S я был вынужден использовать одну таблицу для представления базы и каждый класс, который ее расширит.

Это позволило мне создавать таблицы меньшего размера, потому что у меня был базовый класс, унаследованный примерно 25 различными вариантамидетских классов.Если вы хотите использовать эту функцию в будущем, это может помочь упростить вашу схему.

2 голосов
/ 01 октября 2010

Каковы основные недостатки использования Linq для SQL вместо NHibernate?

Преимущества LINQ to SQL

  • Более продвинутый и простой в использовании (IMHO) синтаксис запросов, в частности, он использует LINQ для выполнения запросов, что дает вам строго типизированные / компилируемые запросы времени. NHibernate дает вам HQL, который, хотя и достаточно мощный, полностью основан на строках. У NHibernate также есть запросы Criteria, которые немного более строго типизированы (все еще некоторые строки), но его синтаксис / API довольно сложно понять.

У NHibernate v2 действительно есть поставщик LINQ, который вы можете скачать, но его немного не хватает (на самом деле много), множество вариантов использования, которые он не поддерживает. NHibernate 3.0 поставляется с собственным встроенным поставщиком LINQ, который намного мощнее, почти наравне с LINQ 2 SQL или EF.


Недостатки в LINQ to SQL

Просто о ВСЕМ еще! Серьезно, с чего мне начать:

  • Простое сопоставление таблиц с сущностями, в отличие от NHibernate, который обладает более мощными возможностями сопоставления, включая: однонаправленные ассоциации, сопоставление компонентов, вы можете сопоставлять коллекции типов значений, таких как public IList<string> Tags {get; set; }, сопоставление наследования (очень мощное), сопоставление Enum плюс еще ...

  • Ваши сущности тесно связаны с LINQ to SQL, что может повлиять на модульное тестирование. NHibernate поддерживает отображение POCO, что важно для реализации слабосвязанной, обслуживаемой, проверяемой модулем базы кода.

  • Поддерживает больше баз данных (SQL Server, MySql, PostgreSQL, Oracle, SQLite и др.). LINQ 2 SQL поддерживает только MS SQL Server.

  • Возможность реализации принципов DDD (Domain Driven Design) в вашем приложении с помощью NHibernate. LINQ 2 SQL является в большей степени ориентированным на базу данных представлением модели вашего домена, тогда как NHibernate принимает более ориентированное на бизнес / поведение представление вашего домена.

Серьезно, взять приложение NHibernate и «понизить» его до LINQ 2 SQL кажется шагом назад. Если вы хотите использовать что-то более Microsofty, по крайней мере, подумайте об использовании Entity Framework 4.0. LINQ 2 SQL имеет свое место с более простыми приложениями с несколькими таблицами, но для чего-то более сложного необходим более мощный ORM.

1 голос
/ 02 октября 2010

, если я правильно помню, Linq2Sql прекрасно не поддерживает отношения между многими и многими таблицами

http://www.chrisbrandsma.com/2007/08/linq-to-sql-many-to-many-tables-and.html

1 голос
/ 01 октября 2010

Вместо полного порта, возможно, все, что вам нужно, это LINQ-ify ваш слой NHibernate ...

http://www.hookedonlinq.com/LINQToNHibernate.ashx

Некоторые дополнительные материалы для чтения:

http://www.caffeinatedcoder.com/linq-to-nhibernate/

Цитата:

Благодаря новому провайдеру NHibernate LINQ я могу теперь работать в режиме, который не только более безопасен, но и гораздо более читабелен.

Посмотрите на эти запросы до и после и судите сами:

До (Criterion API)

   1: public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)
   2: {
   3:     ICriteria criteria = Session.CreateCriteria(typeof(Call))
   4:         .CreateAlias("Customer", "Customer")
   5:         .Add(Restrictions.Gt("StartTime", beginDate))
   6:         .Add(
   7:            Restrictions.Or(
   8:                 Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime")
   9:                 )
  10:             )
  11:         .Add(Restrictions.Eq("Interpreter.Id", interpreterId))
  12:         .AddOrder(Order.Desc("StartTime"))
  13:         .AddOrder(Order.Desc("Customer.Name"));
  14:
  15:     return criteria.List<Call>() as List<Call>;
  16: }

После (LINQ to NHibernate)

   1: public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)
   2: {
   3:     var query = from call in Session.Linq<Call>()
   4:                     where call.StartTime > beginDate
   5:                         && (call.EndTime == null || call.EndTime < DateTime.Now )
   6:                         && call.Interpreter.Id == interpreterId
   7:                     orderby call.StartTime descending, call.Customer.Name
   8:                     select call;
   9:
  10:     return query.ToList();
  11: }
1 голос
/ 01 октября 2010

Когда я создаю приложение с простым доменом и базовой схемой, я люблю Linq2Sql. Linq быстро пишет, и я могу быстро все сделать. Я понимаю, что существует Linq2NHibernate, но я не уверен, какова его зрелость. Некоторые недостатки, IMO для Linq2Sql, должны регенерировать классы и DataContext всякий раз, когда меняется схема, и приходится отображать из сгенерированных Linq2Sql классов в мои доменные объекты. Для небольших легких проектов я действительно не возражаю против этого. Хотя с FluentNHibernate и Linq2NHibernate, я мог бы быть в состоянии быть таким же эффективным с NHibernate, как и с Linq2Sql, но я не пробовал.

Я был в проекте, который использовал Linq2Sql для чрезмерно нормализованной базы данных с несколько сложным доменом, и это был кошмар. Это сработало, и мы смогли добиться некоторой хорошей производительности, но ремонтопригодности практически не было. Но с такой схемой я не уверен, что NHibernate или прямой SQL изменили бы это. Это один из случаев, когда, без сомнения, я думаю, база данных документов была бы идеальным вариантом.

Если бы проект уже был выполнен с помощью NHibernate, и у вас есть такой опыт, я бы его придерживался. Тот факт, что вы можете сопоставить объекты вашего домена, просто великолепен. Генерация кода Linq2Sql может быть проблемой, когда схема изменяется в начале разработки. Кроме того, Linq2Sql фактически мертв. MS кладет все яйца ORM в корзину Entity Framework.

...