Entity Framework 4 vs NHibernate [zamknięty]

114

Dużo się mówiło o pierwszej wersji Entity Framework w sieci (także na stackoverflow) i jest jasne, że nie był to dobry wybór, kiedy mamy już lepszą alternatywę jak NHibernate. Ale nie mogę znaleźć dobrego porównania Entity Framework 4 i NHibernate. Możemy powiedzieć, że obecnie NHibernate jest liderem wśród wszystkich ORMów .NET, ale możemy oczekiwać, że Entity Framework 4 wyprze NHibernate z tej pozycji. Myślę, że jeśli Microsoft naprawdę wprowadził bardzo dobre funkcje do EF4, może dać dobrą konkurencję dla NHibernate, ponieważ ma integrację z Visual Studio, łatwiejszą w obsłudze i zawsze preferowane są produkty MS w większości sklepów.

Deependra Solanky
źródło
31
Chciałbym zaktualizować to porównanie. Czy dużo się wydarzyło od '09?
Phil,

Odpowiedzi:

66

EF4 ma gotową odpowiedź w odniesieniu do rozwoju n-warstwowego w „jednostkach samokierujących”. Nikt nie opublikował porównywalnego kodu dla NHib.

NHib ma wiele funkcji, o których nie wspomniano jako część EF4. Obejmują one integrację pamięci podręcznej drugiego poziomu. Ma również większą elastyczność w mapowaniu dziedziczenia, lepszą integrację z przechowywanymi procesami / funkcjami bazy danych / niestandardowym SQL / wyzwalaczami, obsługę właściwości formuł i tak dalej. IMO jest po prostu bardziej dojrzałe jako ORM.

John Rayner
źródło
13
+1 Masz rację. NH jest po prostu dojrzały. EF nadrobi zaległości do końca roku. Wersja 4.0 ma już dramatyczne wejście. Daj mu trochę czasu, a do połowy 2011 roku będzie kuloodporny.
15
-1 Dla „EF4 ma gotową odpowiedź w odniesieniu do rozwoju n-warstwowego, w„ jednostkach samokierujących ”. Nikt nie opublikował porównywalnego kodu dla NHib.” Jest ISession.Merge w NHibernate, który jest o wiele lepszy niż jednostki Self-Tracking w rozwoju N-Tier.
Alex Burtsev
12
@Alex - W jaki sposób NHibernate jest rozwiązaniem „gotowym do użycia”? Aby wyjaśnic; „Po wyjęciu z pudełka” oznacza, że ​​działa z podstawową instalacją programu Visual Studio. To nieuzasadnione -1 tutaj.
Doctor Jones,
9
@DoctaJonez - Sposób, w jaki to przeczytałem, Alex kwestionował pomysł, że NH nie ma nic porównywalnego z jednostkami samokierującymi, a nie część, że jest „po wyjęciu z pudełka”.
Jerph
2
Właściwie odkryłem, że EF4 ma bardziej elastyczne mapowanie dziedziczenia. Na przykład można użyć 2 tabel (TPT) jako klasy bazowej + klasy poziomu 1 i dodać dyskryminator do tabeli poziomu 1, umożliwiając podział na klasy poziomu 2. W NH dyskryminator można zdefiniować tylko w klasie bazowej.
Danny Varod
37

Aktualizacja: nie korzystałem z Entity Framework od wersji 4.0, więc moja odpowiedź może być nieaktualna. W swoich projektach nadal używam NH lub czystej ADO .NET. I nie chcę nawet patrzeć na to, co nowego w EF od wersji 4.0, ponieważ NH działa doskonale.

Właściwie jest całkiem łatwo je porównać, gdy użyłeś obu. Istnieją poważne ograniczenia związane z EF4, mogę wymienić niektóre, z którymi sam się spotkałem:

Problemy z EF4:

  • Chętne ładowanie i kształtowanie wyniku : System szybkiego ładowania EF4 (Include ("Path")) generuje niewłaściwy kod SQL, z zapętlonymi poleceniami JOIN, który będzie wykonywał tysiące (nie dosłownie) wolniej dla relacji wiele-do-wielu niż ręcznie napisany SQL (to efektywnie bezużyteczne).
  • Materializator nie może zmaterializować powiązanych jednostek : jeśli uważasz, że możesz rozwiązać poprzedni problem, udostępniając własne zapytanie SQL, to się mylisz. EF4 nie może zmaterializować (odwzorować) powiązanych jednostek z zapytania JOIN SQL, może załadować dane tylko z jednej tabeli (więc jeśli masz Order.Product, SELECT * FROM order LEFT JOIN Produkt zainicjuje tylko obiekt Order, Product pozostanie pusty, myślałem, że wszystkie niezbędne dane są pobierane w zapytaniu, aby je zainicjować). Można to rozwiązać za pomocą dodatku społecznościowego EFExtensions, ale kod, który będziesz musiał napisać, jest naprawdę brzydki (próbowałem).
  • Podmioty samo śledzące: Wielu twierdzi, że jednostki samokierujące są fajne w programowaniu N-warstwowym, w tym najlepsza odpowiedź w tym wątku. Myślałem, że nawet nie spróbowałem, mogę powiedzieć, że tak nie jest Każde wejście może zostać sfałszowane, nie możesz po prostu przyjąć zmian, które przesyła Ci użytkownik i zastosować je do bazy danych, dlaczego nie dać użytkownikowi bezpośrednio danych dostęp do bazy? W każdym razie będziesz musiał załadować dane, które użytkownik ma zamiar zmienić z DB, sprawdzić, czy istnieją | nie istnieje, sprawdzić uprawnienia itp. Itp. Nie możesz ufać użytkownikowi co do stanu jednostki, którą wysyła na serwer, i tak to zrobisz musisz załadować tę jednostkę z DB i określić jej stan i inne rzeczy, więc te informacje są bezużyteczne, podobnie jak jednostki Self-Tracking, chyba że zrobisz prywatny zaufany system n-warstwowy do użytku wewnętrznego, w takim przypadku możesz podać po prostu zwykły Dostęp do bazy danych.

  • Rejestrowanie, zdarzenia, integracja logiki biznesowej: EF4 jest jak czarna skrzynka, coś robi i nie masz pojęcia, co robi. Jest tylko jedno zdarzenie OnSavingChanges, w którym możesz umieścić logikę biznesową, którą musisz uruchomić, zanim coś się stanie z DB, a jeśli musisz wprowadzić pewne zmiany do obiektów biznesowych, zanim coś się wydarzy, będziesz musiał kopać w ObjectStateManager, a to jest naprawdę brzydkie kod może stać się ogromny. Jeśli na przykład używasz wzorca repozytorium i tego, co ma być powiadamiane o zmianach wprowadzonych w DB w sposób czystego obiektu, będziesz miał trudności z zrobieniem tego z EF.

  • Rozszerzalność: Cały kod EF jest prywatny i wewnętrzny, jeśli coś ci się nie podoba (i nie spodoba ci się DUŻO, jeśli poważnie myślisz o używaniu EF), w żaden sposób nie zmienisz tego w łatwy sposób, W rzeczywistości jestem pewien łatwiej jest napisać własny ORM od zera (zrobiłem), a następnie sprawić, by EF działał tak, jak potrzebujesz. Jako przykład spójrz na źródło EFExtensions, jest ono oparte na metodach rozszerzeń i różnych "hackach", aby EF był trochę bardziej użyteczny, a kod jest dość brzydki (i nie jest to wina autorów, kiedy wszystko w EF jest prywatne, jest to jedyne sposób na przedłużenie).

Nadal mogę pisać złe rzeczy na temat EF i tego, jak bolesna była dla mnie praca z nim przez około 20 stron, a może tak będzie.

A co z NHibernate? To zupełnie inny poziom, to tak, jakby porównywać PHP z C #, EF4 jest jak w epoce kamienia łupanego, to tak, jakby EF jest 10 lat za nim, a następnie NHibernate w trakcie rozwoju, i tak naprawdę jest, Hibernate został uruchomiony w 2001 roku. Jeśli masz wolny czas nauczyć się i włączyć Nhibernate, zrób to.

Alex Burtsev
źródło
1
EF został wydany na licencji Apache 2, co powinno pomóc w rozszerzaniu.
CMircea
@MirceaChirea Thats, świetna wiadomość, nie spodziewałem się tego, przeglądając teraz kod źródłowy EF, całkiem ciekawa lektura.
Alex Burtsev
2
-1 za kilka stwierdzeń poprzedzonych wyrażeniem „Nie użyłem tego, ale i tak mówię”.
Kyeotic
@Tyrsius Moja odpowiedź została napisana prawie 3 lata temu, od dawna nie używam EF, niektóre rzeczy mogą się poprawić, możesz edytować moją odpowiedź, aby zaktualizować ją do aktualnego statusu EF.
Alex Burtsev
2
Przyznajesz, że nigdy nie używałeś jednostek samokierujących, ale jednak je odrzucasz. Co powiesz tylko na to, co wiesz, i pomiń ignoranckie domysły, zwłaszcza że cały ten akapit jest prawie błędny.
Tom Halladay
25

To jest ta rzecz. Moim zdaniem NHibernate i Entity Framework są tak naprawdę przeznaczone dla dwóch różnych odbiorców. NHibernate byłby moim wyborem w budowaniu systemu ze złożonymi odwzorowaniami, formułami i ograniczeniami (w zasadzie wszystko, co jest przedsiębiorstwem). Gdybym chciał działać w terenie z prostym dostępem do danych, użyłbym Entity Framework lub LINQ-to-SQL. NHibernate nie ma wyraźnego doświadczenia „przeciągnij i upuść”, podobnie jak EF. Obie mają swoje mocne i słabe strony. Szczerze mówiąc, porównanie ich jabłek do jabłek nie prowadzi do niczego.

zowens
źródło
13
Czy próbowałeś ActiveWriter? Entity Framework jest całkowicie ukierunkowany na przestrzeń przedsiębiorstwa. Nie zgadzam się z większością tego, co powiedziałeś.
Michael Maddox
1
Nie zgadzam się ze wszystkim, co chcesz, ale fakt, że NHibernate istnieje dłużej, jest czymś, czego przedsiębiorstwa NIE WOLNO przeoczyć.
zowens
21
-1 To nie jest dobre porównanie NHibernate i Entity Framework. Porównanie tych dwóch przez wrzucenie EF z LINQ do SQL po prostu b / c, które ma przeciąganie i upuszczanie, jest w najlepszym przypadku nieszczere. Jeśli chodzi o złożoność, czym właściwie jest NHibernate, czego nie potrafi EF 4?
Kevin Babcock
14
Buforowanie drugiego poziomu, ich zapytania są WYSOCE zoptymalizowane, NH wymusza użycie wzorca UnitOfWork, a mapowania nie są zablokowane w jednym pliku. Moim zdaniem (z doświadczenia) jest to, że NHibernate jest bardziej wydajne. Nie zgadzam się ze mną w tej sprawie, ale powiedziałem, że to moja opinia. Mój punkt widzenia jest NADAL aktualny, OBA mają swoje mocne i słabe strony. Nikt nie może temu zaprzeczyć.
zowens
2
@ MakerOfThings7 to żałosne ... to całe pytanie jest subiektywne. Obudź się ...
zowens
23

Jeśli myślisz, że kiedykolwiek będziesz chciał uruchomić swój kod na Mono, NHibernate jest prawdopodobnie lepszym wyborem, bez względu na to, co mówią listy kontrolne funkcji ...

Edycja, 13.08.2012:

Entity Framework została oparta na oprogramowaniu typu open source i jest teraz uwzględniona w programie Mono od 2.11.3. Ta odpowiedź jest już nieaktualna i nie należy na niej polegać.

http://weblogs.asp.net/scottgu/archive/2012/07/19/entity-framework-and-open-source.aspx

Joel Mueller
źródło
Rzeczywiście, na stronie mono-project.com/Compatibility jest napisane „EntityFrameworks - Not available.” I wygląda na to, że nikt nie jest zainteresowany jego wdrożeniem. Więc przynajmniej przez kilka lat to NHibernate albo nic.
user276648
12

Wydaje mi się, że EF4.0 przeszedł długą drogę od 1.0 i dogania Nhibernate pod względem funkcjonalności, ale to jeszcze nie wszystko.

Jednak jest to Microsoft, po wyjęciu z pudełka i robi 100% tego, czego potrzebuje 95% aplikacji. Jednak NHibernate robi to samo od lat. Wersja 5.0 lub 6.0 może nadrobić zaległości, a nawet przewyższyć NHibernate.

Oto moja rada - jeśli masz czas, aby nauczyć się obu, zrób to. Istnieje kilka powodów, dla których warto wybrać jeden z nich. Jeśli piszesz kod dla korporacji, realistyczne jest oczekiwanie, że będą zdolni pracownicy, którzy będą zaznajomieni z EF, tak jak jest to we wszystkich książkach i czego dzieci uczą się na studiach. Jeśli EF spełni twoje wymagania (pomyśl o tym długo i ciężko, zanim powiesz tylko tak), to na razie jest to idealnie dobre rozwiązanie i za kilka lat może (ok, najprawdopodobniej) przewyższyć NHibernate.

NHibernate jest bardzo dojrzałym produktem z kilkuletnim EF i najprawdopodobniej zrobi wszystko, czego kiedykolwiek zechcesz, a potem trochę. Od jakiegoś czasu jest to najlepszy ORM i wiele osób z niego korzysta.

Dziekan
źródło
10

Myślę, że fakt, że EF 4 będzie miał możliwość korzystania z POCO i odroczonego leniwego ładowania będzie bardzo duży. Zdecydowanie mogłem zobaczyć, jak zyskuje na popularności dzięki nowej wersji.

YeahStu
źródło
7
Nie zapomnij o obsłudze LINQ. NHibernate nadal nie jest w tym dobry.
Arnis Lapsa
1
@Arnis, czy możesz podać linki potwierdzające tę opinię?
Michael Maddox
2
@Michael jest to oczywiste, gdy przeglądasz posty na blogu Ayande na ten temat. Obecnie LINQ to NH bazuje na kryteriach API. Kryteria API nie zezwalają na niektóre z bardziej złożonych funkcji zapytań, jakie może mieć HQL. Następna wersja LINQ to NH będzie używać HQL zamiast interfejsu API kryteriów.
zowens
5

Istnieje oczywisty trend zwiększania popularności EF w porównaniu z NHibernate, patrz zdjęcie.

NHibernate a Entity Framework

Tomas Kubes
źródło
Jaki jest sens twojej odpowiedzi? yourlogicalfallacyis.com/bandwagon
Răzvan Flavius ​​Panda
Że zgodnie z trendem ludzie z czasem coraz częściej zaczynają używać googlowania EntityFramework. I mogą mieć ku temu dobry powód. Może zaczęło być lepiej.
Tomas Kubes,
Mogłoby tak być, może być również tak, że to, co jest domyślnie sugerowane, ma być używane przez państwa członkowskie. Również oprzyrządowanie dla EF jest całkiem dobre.
Răzvan Flavius ​​Panda
4

Moje 2 centy: używamy ef na naszym komputerze stacjonarnym do niektórych cahing itp. - bez hibernacji. NHib po stronie serwera - wykorzystując sesje bezstanowe, generowanie hilo id i partie. Jest dość szybki we wstawianiu 3k + wiadomości w db na sekundę. Jest również bardzo elastyczny i obsługuje wiele dbs, co jest kluczowe dla naszego produktu.

Aleksei Anufriev
źródło
3

Mapowanie bezpośrednio do procedur składowanych z kombinacją Linq dla warstwy logicznej wydaje się najłatwiejszym podejściem. Brak xml. Generuj sql tylko dla interesujących zapytań, które są rzadziej używane lub nie nadają się do procedur składowanych.

Obiekty ładują się i przechowują za pomocą standardowych SP. Takie podejście pozwala na użycie dwóch loginów sql. Jeden dla dostępu do klasy przez SP (uprawnienia tylko do wykonywania) i jeden dla logicznego modułu linq, który umożliwia bezpośredni dostęp do tabeli.

Andrzej
źródło
1

Wybór między ORMami według popularności nie jest najlepszym rozwiązaniem. Próbowałem przenieść się do EF przez ostatnie 2 lata i wszystko, co mogę powiedzieć, to dlaczego, do cholery, wciąż próbuję?

ATM mój punkt widzenia na temat EF to: „Jest stworzony dla naprawdę małych, bardzo małych systemów bitowych z nie więcej niż 3 tabelami z mniej niż 1 relacją (0 jest lepsze)”.

A dlaczego tak myślę? 1. Spróbuj zaktualizować odłączony wykres i zobacz zarys modelu;

  1. Spróbuj utworzyć TPH z głęboko odziedziczonymi drzewami, a przekonasz się, że jesteś przywiązany do jednej hierarchii lub system się zepsuje.

  2. Spróbuj wykonać bardziej uciążliwe zapytania i obserwuj, jak cały system pożera stos: D ... przepełnienia zdarzają się bardzo często.

  3. Typy danych Map XML są oparte na rozszerzeniach lub najbardziej „znienawidzonych” właściwościach NotMapped ... a jest jeszcze gorzej.

  4. Spróbuj zmieszać zapytanie SQL z Linq, aby uzyskać bardziej precyzyjne zapytania, a złamiesz ścianę lol.

  5. I ostatnia i najważniejsza rzecz, EF nie obsługuje formuły właściwości („niesamowite zasoby, które NH ma dla starszych baz danych”) i nie obsługuje złożonych mapowań typów dla tej samej tabeli i powiązanych tabel.

To moje 10 cm3.

Moisés Gonçalves
źródło