NHibernate vs LINQ to SQL

Jako ktoś, kto nie używał żadnej z tych technologii w rzeczywistych projektach zastanawiam się, czy ktoś wie, jak te dwie technologie się uzupełniają i jak bardzo ich funkcjonalności nakładają się na siebie?

Author: Rex M, 2008-08-26

9 answers

LINQ do SQL wymusza użycie wzorca table-per-class. Korzyści płynące z używania tego wzorca są takie, że jest on szybki i łatwy do wdrożenia i zajmuje bardzo mało wysiłku, aby Twoja domena działała w oparciu o istniejącą strukturę bazy danych. W przypadku prostych aplikacji jest to całkowicie dopuszczalne( a często nawet pożądane), ale w przypadku bardziej złożonych aplikacji twórcy często sugerują użycie wzorca domain driven design (co jest tym, co NHibernate ułatwia).

Problem z wzorcem table-per-class polega na tym, że struktura bazy danych ma bezpośredni wpływ na projekt domeny. Na przykład, załóżmy, że masz tabelę klientów z następującymi kolumnami, aby przechowywać podstawowe informacje o adresie klienta:

  • StreetAddress
  • Miasto
  • Stan
  • Zip

Teraz powiedzmy, że chcesz dodać kolumny dla adresu mailowego klienta, a więc dodać w następujących kolumnach do Tabela klientów:

  • MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

Używając LINQ do SQL, obiekt Klienta w Twojej domenie miałby teraz właściwości dla każdej z tych ośmiu kolumn. Ale gdybyś stosował wzorzec projektowy oparty na domenie, prawdopodobnie stworzyłbyś klasę adresową i miał klasę klienta posiadającą dwie właściwości adresowe, jedną dla adresu pocztowego i jedną dla ich bieżącego adresu.

To prosty przykład, ale pokazuje, jak wzór table-per-class może prowadzić do nieco śmierdzącej domeny. Koniec końców, to zależy od Ciebie. Ponownie, dla prostych aplikacji, które potrzebują tylko podstawowej funkcjonalności CRUD (tworzenie, odczyt, aktualizacja, usuwanie), LINQ do SQL jest idealny ze względu na prostotę. Ale osobiście lubię używać NHibernate, ponieważ ułatwia czystszą domenę.

Edit: @ lomaxx-tak, przykład, którego użyłem był uproszczony i mógł być zoptymalizowany do pracy z LINQ do SQL. Chciałem zachowaj go jak najbardziej podstawowe, aby dojechać do domu punkt. Chodzi jednak o to, że istnieje kilka scenariuszy, w których posiadanie struktury bazy danych określającej strukturę domeny byłoby złym pomysłem lub przynajmniej doprowadziłoby do nieoptymalnego projektu OO.

 112
Author: Kevin Pang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 14:57:12

Dwa punkty, które dotychczas zostały pominięte:

Również nowy płynny interfejs do Nhibernate wydaje się mniej bolesne skonfigurowanie mapowania Nhibernate. (Usunięcie jednego z punktów bólowych Nhibernate)


Update

Linq do Nhiberate jest lepszy w Nhiberate v3, który jest teraz w alpha . Wygląda na to, że nhiberate v3 może pojawić się pod koniec tego roku.

Praca ramki encji od.Net 4 również zaczyna wyglądać jak prawdziwa opcja.

 26
Author: Ian Ringrose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-04 11:51:59

@Kevin: myślę, że problem z prezentowanym przykładem polega na tym, że używasz słabego projektu bazy danych. Myślałem, że stworzysz tabelę klientów i tabelę adresów i znormalizujesz tabele. Jeśli to zrobisz, możesz zdecydowanie użyć Linq do SQL dla scenariusza, który sugerujesz. Scott Guthrie ma świetną serię postów na temat korzystania z Linq do SQL które zdecydowanie sugerowałbym sprawdzić.

Chyba nie można powiedzieć, że Linq i NHibernate uzupełniają każde inne, ponieważ oznaczałoby to, że mogą być używane razem, i chociaż jest to możliwe, o wiele lepiej wybrać jeden i trzymać się go.

NHibernate pozwala na mapowanie tabel baz danych do obiektów domeny w bardzo elastyczny sposób. Umożliwia również korzystanie z HBL do odpytywania bazy danych.

Linq do SQL pozwala również na mapowanie obiektów domeny do bazy danych, jednak używa składni zapytań Linq do zapytania bazy danych

Główną różnicą jest to, że Składnia zapytań Linq jest sprawdzana podczas kompilacji przez kompilator, aby upewnić się, że zapytania są poprawne.

Niektóre rzeczy, które należy pamiętać o linq jest to, że jest on dostępny tylko w. Net 3.x i jest obsługiwana tylko w VS2008. NHibernate jest dostępny w wersji 2.0 i 3.x oraz VS2005.

Należy pamiętać, że NHibernate nie generuje obiektów domeny ani nie generuje plików mapowania. Musisz to zrobić ręcznie. LINQ can
zrób to automatycznie dla Ciebie.

 23
Author: lomaxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 00:20:58

Fluent NHibernate może generować pliki mapowania w oparciu o proste konwencje. Brak zapisu XML i mocno wpisany.

Ostatnio pracowałem nad projektem, w którym musieliśmy zmienić Linq na SQL na NHibernate ze względu na wydajność. Szczególnie sposób materializacji obiektów L2S wydaje się wolniejszy niż ditto NHibernate i zarządzanie zmianami jest również dość powolne. I może być trudno wyłączyć zarządzanie zmianami w określonych scenariuszach, gdzie nie jest to potrzebne.

Jeśli zamierzasz używać swoich jednostek odłączonych od DataContext - na przykład w scenariuszach WCF-możesz mieć wiele problemów z podłączeniem ich do DataContext ponownie w celu aktualizacji zmian. Nie miałem z tym żadnych problemów z NHibernate.

Z L2S będzie mi brakować głównie generowania kodu, który utrzymuje relacje na bieżąco na obu końcach encji. Ale myślę, że NHibernate również ma do tego narzędzia...

 7
Author: asgerhallas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-21 19:57:43

Możesz wyjaśnić co masz na myśli przez "LINQ"?

LINQ nie jest technologią dostępu do danych, to tylko funkcja języka, która obsługuje zapytania jako natywną konstrukcję. Może odpytywać dowolny model obiektowy, który obsługuje określone interfejsy (np. IQueryable).

Wiele osób odnosi się do LINQ do SQL jako LINQ, ale to wcale nie jest poprawne. Microsoft udostępnił właśnie LINQ dla podmiotów z. NET 3.5 SP1. Dodatkowo NHibernate ma interfejs LINQ, więc możesz użyć LINQ i NHibernate, aby uzyskać Twoje dane.

 5
Author: Jon Galloway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 21:45:57

Przez LINQ, zakładam, że masz na myśli LINQ do SQL, ponieważ LINQ sam w sobie nie ma powiązanych z nim "wejść" do bazy danych. Jest to po prostu język zapytań, który ma mnóstwo cukru składniowego, aby wyglądał na SQL-owski.

W bardzo podstawowych przykładach, NHibernate i LINQ do SQL wydają się rozwiązywać ten sam problem. Po otrzymaniu przepustki szybko zdajesz sobie sprawę, że NHibernate ma wsparcie dla wielu funkcji, które pozwalają tworzyć prawdziwie bogate modele domen. Jest też LINQ do Projekt NHibernate, który pozwala na użycie LINQ do odpytywania NHibernate w taki sam sposób, jak użycie LINQ do SQL.

 2
Author: Ryan Rinaldi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 21:49:20

Najpierw rozdzielmy dwie różne rzeczy: Modelowanie baz danych dotyczy danych, podczas gdy modelowanie obiektowe dotyczy podmiotów i relacji.

Zaletą Linq-to-SQL jest szybkie generowanie klas ze schematu bazy danych, aby mogły być używane jako obiekty active record(Zobacz definicję wzorca projektowego active record).

Zaletą NHibernate jest umożliwienie elastyczności między modelowaniem obiektowym a modelowaniem baz danych. Bazy danych można modelować tak, aby jak najlepiej odzwierciedlały Twoje dane, na przykład biorąc pod uwagę wydajność. Podczas gdy modelowanie obiektów najlepiej odzwierciedli elementy reguły biznesowej przy użyciu podejścia takiego jak projektowanie oparte na domenie. (zobacz komentarz Kevina Panga)

Ze starszymi bazami danych o słabych konwencjach modelowania i / lub nazewnictwa, Linq-to-SQL będzie odzwierciedlać te niechciane struktury i nazwy dla Twoich klas. Jednak NHibernate może ukryć ten bałagan z maperami danych.

W projektach greenfield, gdzie bazy danych mają dobre nazewnictwo i niska złożoność, Linq-to-SQL może być dobrym wyborem.

Jednak możesz użyć Fluent NHibernate z auto-mappingami w tym samym celu z mapowaniem jako convention. W tym przypadku nie martw się o żadnych maperów danych z XML lub C# i pozwól NHibernate wygenerować schemat bazy danych z jednostek na podstawie Konwencji, które można dostosować.

Z drugiej strony krzywa uczenia się Linq-to-SQL jest mniejsza niż NHibernate.

 1
Author: Humberto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-06 16:35:53

LUB możesz skorzystać z projektu Castle ActiveRecords. Używam tego przez krótki czas, aby stworzyć nowy kod dla starszego projektu. Używa NHibernate i działa na wzorcu active record (zaskakujące, biorąc pod uwagę jego nazwę, którą znam). Nie próbowałem, ale zakładam, że gdy już go użyjesz, jeśli poczujesz potrzebę bezpośredniego wsparcia NHibernate, nie będzie to zbyt wiele dla części lub całego twojego projektu.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 22:13:14

Jak napisałeś " dla osoby, która nie użyła żadnego z nich" LINQ to SQL jest łatwy w użyciu, więc każdy może z niego łatwo korzystać Wspiera również procedury, co pomaga przez większość czasu. Załóżmy, że chcesz pobrać dane z więcej niż jednej tabeli, a następnie napisz procedurę i przeciągnij ją do designera, a ona utworzy wszystko dla Ciebie, Załóżmy, że Twoja nazwa procedury to "CUSTOMER_ORDER_LINEITEM", która pobiera rekord ze wszystkich tych trzech tabel, a następnie po prostu napisz

MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();

You can use you zapisuje również obiekt w pętli foreach, która nie jest obsługiwana przez NHibernate

 0
Author: Ali Adravi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-20 19:01:52