Odpowiedzi:
LINQ to SQL wymusza użycie wzorca table-per-class. Zaletą korzystania z tego wzorca jest to, że jest szybki i łatwy w implementacji, a uruchomienie domeny w oparciu o istniejącą strukturę bazy danych zajmuje bardzo niewiele wysiłku. W przypadku prostych aplikacji jest to całkowicie akceptowalne (a często nawet preferowane), ale w przypadku bardziej złożonych aplikacji programiści często sugerują użycie zamiast tego wzorca projektowania opartego na domenie (co ułatwia NHibernate).
Problem z wzorcem tabeli dla klasy polega na tym, że struktura bazy danych ma bezpośredni wpływ na projekt domeny. Załóżmy na przykład, że masz tabelę Klienci z następującymi kolumnami zawierającymi podstawowe informacje o adresie klienta:
Załóżmy teraz, że chcesz również dodać kolumny dla adresu pocztowego klienta, więc dodasz następujące kolumny do tabeli Klienci:
Korzystając z LINQ to SQL, obiekt Customer w Twojej domenie miałby teraz właściwości dla każdej z tych ośmiu kolumn. Ale gdybyś postępował zgodnie ze wzorcem projektowym opartym na domenie, prawdopodobnie utworzyłbyś klasę Adres i miałbyś klasę klienta mieć dwie właściwości Adres, jedną dla adresu pocztowego, a drugą dla ich aktualnego adresu.
To prosty przykład, ale pokazuje, w jaki sposób wzorzec tabeli na klasę może prowadzić do cuchnącej domeny. Ostatecznie to zależy od Ciebie. Ponownie, w przypadku prostych aplikacji, które potrzebują tylko podstawowych funkcji CRUD (tworzenie, odczytywanie, aktualizowanie, usuwanie), LINQ to SQL jest idealne ze względu na prostotę. Ale osobiście lubię używać NHibernate, ponieważ ułatwia to czystszą domenę.
Edycja: @lomaxx - Tak, przykład, którego użyłem, był uproszczony i mógł zostać zoptymalizowany do dobrej współpracy z LINQ to SQL. Chciałem, aby było to możliwie podstawowe, aby doprowadzić do sedna sprawy. 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 prowadziłoby do nieoptymalnego projektu OO.
Dwie kwestie, które do tej pory zostały pominięte:
LINQ to SQL nie działa z Oracle ani żadną bazą danych poza SqlServer. Jednak 3rd strony oferują lepsze wsparcie dla Oracle, np dotConnect Devart jest , DbLinq , Mindscape za Lightspeed i ALinq . (Nie mam z nimi żadnych osobistych doświadczeń)
Linq do NHibernate pozwala używać Linq z Nhiberate, więc może usunąć powód, dla którego nie należy używać.
Wydaje się, że nowy, płynny interfejs Nhibernate sprawia, że konfigurowanie mapowania Nhibernate jest mniej bolesne. (Usunięcie jednego z punktów bólu Nhibernate)
Aktualizacja
Linq do Nhiberate jest lepszy w Nhiberate v3, który jest teraz w wersji alfa . Wygląda na to, że Nhiberate v3 może zostać dostarczony pod koniec tego roku.
Podmiot Rama Praca jako .NET 4 jest także zaczynają wyglądać jak prawdziwy opcji.
@Kevin: Myślę, że problem z przykładem, który prezentujesz, polega na tym, że używasz kiepskiego projektu bazy danych. Pomyślałbym, że utworzysz tabelę klientów i tabelę adresów i znormalizujesz tabele. Jeśli to zrobisz, zdecydowanie możesz użyć Linq To SQL w scenariuszu, który sugerujesz. Scott Guthrie ma świetną serię postów na temat używania Linq To SQL, które zdecydowanie polecam.
Nie sądzę, aby można było powiedzieć, że Linq i NHibernate uzupełniają się nawzajem, ponieważ sugerowałoby to, że mogą być używane razem, i chociaż jest to możliwe, o wiele lepiej jest wybrać jeden i trzymać się go.
NHibernate umożliwia bardzo elastyczne mapowanie tabel bazy danych do obiektów domeny. Umożliwia także użycie HBL do przeszukiwania bazy danych.
Linq to SQL umożliwia również mapowanie obiektów domeny do bazy danych, jednak używa składni zapytania Linq do wysyłania zapytań do bazy danych
Główna różnica polega na tym, że składnia zapytania Linq jest sprawdzana w czasie kompilacji przez kompilator, aby upewnić się, że zapytania są prawidłowe.
Należy pamiętać o tym, że linq jest dostępny tylko w .net 3.xi jest obsługiwany tylko w VS2008. NHibernate jest dostępny w wersjach 2.0 i 3.x oraz VS2005.
W przypadku NHibernate należy pamiętać o tym, że nie generuje on obiektów domeny ani plików mapowania. Musisz to zrobić ręcznie. Linq może
to zrobić automatycznie.
Fluent NHibernate może generować pliki mapowań w oparciu o proste konwencje. Bez pisania w XML i silnie wpisane.
Niedawno pracowałem nad projektem, w którym ze względów wydajnościowych musieliśmy zmienić Linq na SQL na NHibernate. Zwłaszcza sposób materializacji obiektów w L2S wydaje się wolniejszy niż w przypadku NHibernate, a zarządzanie zmianami jest również dość powolne. Wyłączenie zarządzania zmianami może być trudne w określonych scenariuszach, w których nie jest to potrzebne.
Jeśli zamierzasz używać jednostek odłączonych od DataContext - na przykład w scenariuszach WCF - możesz mieć wiele problemów z ponownym połączeniem ich z DataContext w celu zaktualizowania zmian. Nie miałem z tym żadnych problemów z NHibernate.
To, czego będzie mi brakowało w L2S, to głównie generowanie kodu, który utrzymuje aktualne relacje na obu końcach jednostek. Ale wydaje mi się, że istnieje kilka narzędzi dla NHibernate, które również to robią ...
.ObjectTrackingEnabled = false
na swój DataContext
byłby rozwiązany problem zmiany śledzenia. Tak długo, jak kupujesz wzorzec jednostki pracy i nie chcesz robić DDD, Linq-to-SQL naprawdę zapewnia.
Czy możesz wyjaśnić, co rozumiesz przez „LINQ”?
LINQ nie jest technologią dostępu do danych, to tylko funkcja języka, która obsługuje zapytania jako konstrukcję natywną. Może odpytać dowolny model obiektowy, który obsługuje określone interfejsy (np. IQueryable).
Wiele osób odnosi się do LINQ To SQL jako LINQ, ale to wcale nie jest poprawne. Firma Microsoft właśnie wydała LINQ To Entities z .NET 3.5 SP1. Ponadto NHibernate ma interfejs LINQ, więc możesz użyć LINQ i NHibernate, aby uzyskać dostęp do swoich danych.
Zakładam, że przez LINQ masz na myśli LINQ to SQL, ponieważ LINQ sam w sobie nie ma skojarzonych z nim „operacji” w bazie danych. To tylko język zapytań, który ma mnóstwo cukru składniowego, aby wyglądał jak SQL.
W bardzo podstawowych z podstawowych przykładów wydaje się, że NHibernate i LINQ to SQL rozwiązują ten sam problem. Kiedy już przejdziesz, szybko zdasz sobie sprawę, że NHibernate obsługuje wiele funkcji, które pozwalają na tworzenie naprawdę bogatych modeli domen. Istnieje również projekt LINQ to NHibernate, który umożliwia używanie LINQ do wykonywania zapytań NHibernate w taki sam sposób, jak w przypadku korzystania z LINQ to SQL.
Najpierw oddzielmy dwie różne rzeczy: modelowanie baz danych dotyczy danych, podczas gdy modelowanie obiektowe dotyczy jednostek i relacji.
Zaletą Linq-to-SQL jest szybkie generowanie klas ze schematu bazy danych, dzięki czemu można ich używać jako obiektów rekordów aktywnych (patrz definicja wzorca projektowania rekordów aktywnych).
Zaletą NHibernate jest zapewnienie elastyczności między modelowaniem obiektów a modelowaniem w bazie danych. Bazę danych można modelować tak, aby jak najlepiej odzwierciedlała dane, biorąc pod uwagę na przykład wydajność. Podczas gdy modelowanie obiektów najlepiej odzwierciedla elementy reguły biznesowej przy użyciu podejścia, takiego jak projektowanie oparte na domenie. (patrz komentarz Kevina Panga)
W przypadku starszych baz danych ze słabymi konwencjami modelowania i / lub nazewnictwa, Linq-to-SQL odzwierciedli te niechciane struktury i nazwy w Twoich klasach. Jednak NHibernate może ukryć ten bałagan dzięki mapowaniu danych.
W projektach od podstaw, w których bazy danych mają dobre nazewnictwo i małą złożoność, Linq-to-SQL może być dobrym wyborem.
Możesz jednak użyć Fluent NHibernate z automatycznym mapowaniem do tego samego celu z mapowaniem jako konwencją. W tym przypadku nie martw się o żadne mapowanie danych z XML lub C # i pozwól NHibernate wygenerować schemat bazy danych z twoich encji w oparciu o konwencję, którą możesz dostosować.
Z drugiej strony krzywa uczenia się Linq-to-SQL jest mniejsza niż NHibernate.
Lub możesz użyć projektu Castle ActiveRecords. Używam tego przez krótki czas, aby przyspieszyć nowy kod dla starszego projektu. Używa NHibernate i działa na wzorze aktywnego rekordu (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 skorzystania ze wsparcia NHibernate, nie byłoby to zbyt trudne dla części lub całego projektu.
Jak napisałeś „dla osoby, która nie korzystała z żadnego z nich” LINQ to SQL jest łatwy w użyciu, więc każdy może z niego łatwo korzystać. Obsługuje również procedury, które pomagają w większości przypadków. Załóżmy, że chcesz pobrać dane z więcej niż jednej tabeli, a następnie napisz procedurę i przeciągnij tę procedurę do projektanta, a utworzy ona wszystko za Ciebie. Załóżmy, że nazwa procedury to „CUSTOMER_ORDER_LINEITEM”, która pobiera rekord ze wszystkich tych trzech tabel, a następnie po prostu pisze
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
możesz również użyć obiektu you records w pętli foreach, co nie jest obsługiwane przez NHibernate