Entity Framework VS LINQ do SQL VS ADO.NET z procedurami przechowywanymi? [Zamknięte]

430

Jak oceniasz każdy z nich pod względem:

  1. Wydajność
  2. Szybkość rozwoju
  3. Czysty, intuicyjny, łatwy w utrzymaniu kod
  4. Elastyczność
  5. Ogólnie

Lubię mój SQL i dlatego zawsze byłem zagorzałym fanem ADO.NET i procedur przechowywanych, ale ostatnio bawiłem się Linq na SQL i byłem zdumiony tym, jak szybko spisałem moją warstwę DataAccess i postanowiłem wydać jakiś czas naprawdę rozumiem albo Linq do SQL albo EF ... albo żaden?

Chcę tylko sprawdzić, czy żadna z tych technologii nie ma wielkiej wady, która sprawiłaby, że mój czas badań byłby bezużyteczny. Np. Wydajność jest okropna, fajna dla prostych aplikacji, ale do tej pory może Cię zabrać.

Aktualizacja: Czy możesz skoncentrować się na EF VS L2S VS SP zamiast na ORM VS SP. Interesuje mnie głównie EF VS L2S. Chciałbym jednak porównać je również z zapisanymi procesami, ponieważ zwykły SQl jest czymś, o czym dużo wiem.

BritishDeveloper
źródło
94
nie konstruktywne, a jednak tyle głosów? ...;)
BritishDeveloper
34
Nie rozumiem, dlaczego ktoś nazwał to niekonstruktywnym. Wydaje mi się to naprawdę dobre. +1 ode mnie
Thanushka
10
To moim zdaniem doskonałe pytanie. Osobiście zauważyłem, że Entity Framework i wszystkie podobne ORM są tam wolniejsze w porównaniu do zwykłego / prostego kodu ADO.Net. Zrobiłem ten test 2 lata temu, a potem jeszcze tydzień temu. Nie jestem pewien, jak LINQ do SQL wypada w porównaniu z EF. Ale ADO.Net zawsze będzie najlepszy pod względem wydajności. Jeśli chcesz zaoszczędzić czas deweloperów, Entity Framework jest dobrym narzędziem, ale zdecydowanie nie wtedy, gdy najważniejsza jest wydajność.
Sunil
2
@Timeless: Istnieje tendencja do polegania na mechanizmach baz danych. Każdy silnik bazy danych ma swój własny język procedur składowanych, więc można się uczyć. 99,9% programistów może polegać na ORM, który wytwarza całkiem niezły kod i automatycznie tworzy SQL. Różnica wydajności jest znikoma w przypadku zwykłego CRUD. Procedury przechowywane są trudniejsze do opracowania i utrzymania. Kilka lat temu, kiedy nie było ORM i nic nie zostało wygenerowane magicznie i automatycznie z bazy danych. Pisanie SP było uważane za mało czasochłonne, ponieważ było alternatywą do pisania instrukcji SQL w aplikacji.
LukLed
4
@Sunil ma rację, ale nie jest wystarczająco pracowity. Problem polega na tym, że wszyscy myślą, że ich główną troską jest wydajność aplikacji. Kiedy mówię o aplikacjach, które wymagają najwyższej wydajności, myślę o poważnych transakcjach MMO C ++ lub dużych transakcjach bazodanowych skierowanych do klientów w dużych milionach. Naprawdę powinieneś skupić się na obiektowych zasadach, takich jak łatwość konserwacji , czytelność , ignorancja w utrzymywaniu i separacja logiki domen . Zwłaszcza, gdy wzrost wydajności jest niewielki w najlepszym wypadku lub w wielu przypadkach nie występuje.
Suamere

Odpowiedzi:

430

Po pierwsze, jeśli zaczynasz nowy projekt, przejdź do Entity Framework („EF”) - teraz generuje on znacznie lepszy SQL (bardziej niż Linq to SQL) i jest łatwiejszy w utrzymaniu i bardziej wydajny niż Linq to SQL („ L2S ”). Począwszy od wydania .NET 4.0, uważam Linq do SQL za przestarzałą technologię. MS był bardzo otwarty, aby nie kontynuować dalszego rozwoju L2S.

1) Wydajność

Trudno jest odpowiedzieć. W przypadku większości operacji z pojedynczą jednostką ( CRUD ) można znaleźć prawie równoważną wydajność we wszystkich trzech technologiach. Musisz wiedzieć, jak działają EF i Linq na SQL, aby w pełni wykorzystać je. W przypadku dużych operacji, takich jak kwerendy odpytywania, możesz chcieć, aby EF / L2S „skompilowała” kwerendę encji tak, aby struktura nie musiała stale regenerować SQL, lub możesz mieć problemy ze skalowalnością. (zobacz zmiany)

W przypadku aktualizacji zbiorczych, w których aktualizuje się ogromne ilości danych, nieprzetworzony kod SQL lub procedura przechowywana zawsze będą działać lepiej niż rozwiązanie ORM, ponieważ nie trzeba przekazywać danych łączem do ORM, aby wykonać aktualizacje.

2) Szybkość rozwoju

W większości scenariuszy EF wysadzi nagie SQL / przechowywane procy, jeśli chodzi o szybkość rozwoju. Projektant EF może aktualizować model z bazy danych w miarę jego zmian (na żądanie), aby nie napotkać problemów z synchronizacją między kodem obiektu a kodem bazy danych. Jedynym momentem, w którym nie rozważałbym użycia ORM, jest wykonywanie aplikacji typu raportowanie / pulpit nawigacyjny, w której nie przeprowadzasz żadnych aktualizacji, lub gdy tworzysz aplikację tylko w celu wykonania operacji konserwacji danych surowych w bazie danych.

3) Czysty / możliwy do utrzymania kod

Ręce w dół, EF bije SQL / sprocs. Ponieważ relacje są modelowane, sprzężenia w kodzie są stosunkowo rzadkie. W przypadku większości zapytań relacje między podmiotami są prawie oczywiste dla czytelnika. Nie ma nic gorszego niż konieczność przechodzenia od debugowania między poziomami lub przez wiele warstw SQL / środkowych, aby zrozumieć, co faktycznie dzieje się z Twoimi danymi. EF wprowadza model danych do kodu w bardzo wydajny sposób.

4) Elastyczność

Przechowywane procy i surowy SQL są bardziej „elastyczne”. Możesz wykorzystać sproki i SQL do generowania szybszych zapytań w przypadku nieparzystych przypadków, a także możesz wykorzystać natywną funkcjonalność DB łatwiej niż możesz to zrobić za pomocą ORM.

5) Ogólnie

Nie daj się wciągnąć w fałszywą dychotomię wyboru ORM vs korzystania z procedur przechowywanych. Możesz używać obu w tej samej aplikacji i prawdopodobnie powinieneś. Duże operacje masowe powinny odbywać się w procedurach przechowywanych lub SQL (które mogą być faktycznie wywoływane przez EF), a EF powinien być używany do operacji CRUD i większości potrzeb warstwy pośredniej. Być może wolisz użyć SQL do pisania raportów. Myślę, że morał tej historii jest taki sam, jak zawsze. Użyj odpowiedniego narzędzia do pracy. Ale w skrócie jest to, że EF jest obecnie bardzo dobry (od .NET 4.0). Poświęć trochę czasu na czytanie i zrozumienie go dogłębnie, a możesz z łatwością tworzyć niesamowite, wydajne aplikacje.

EDYCJA : EF 5 nieco upraszcza tę część dzięki automatycznie kompilowanym zapytaniom LINQ , ale w przypadku naprawdę dużych ilości rzeczy zdecydowanie musisz przetestować i przeanalizować to, co najlepiej pasuje do Ciebie w prawdziwym świecie.

Dave Markle
źródło
35
Absolutnie genialna odpowiedź. Rzeczywiście używam teraz EF, aby szybko opracować aplikację. Jeśli wydajność stanie się problemem, przechowywane procy zostaną wprowadzone w celu refaktoryzacji źle działających zapytań EF. Dzięki!
BritishDeveloper
17
@BritishDeveloper: Nie zapomnij także o mocy widoków. Odnieśliśmy duży sukces, definiując kilka widoków w naszych projektach L2S i wykorzystując je tam, gdzie wydaje się, że framework pisze słabe zapytania. W ten sposób uzyskujemy wszystkie zalety korzystania z frameworka i wszystkie zalety pisania własnego SQL.
Dave Markle,
5
Korzystam również z widoków;) Więcej jako obejście ograniczenia nieprzekraczania db EF. Dobry pomysł na optymalizację. Dzięki
BritishDeveloper
5
Zdecydowanie świetna odpowiedź. Chciałem tylko dodać obserwację, którą miałem z własnego doświadczenia z L2S vs. EF4. Zamieniono z L2S -> EF4 po tym, jak zdaliśmy sobie sprawę, że możemy używać kilku różnych RDMBS ... ale, mimo że nadal działam MSSQL, spadek wydajności pokazał się głównie w obszarze GUI mojej aplikacji. Powiązanie danych z zestawem wyników w L2S było znacznie szybsze niż EF4. To jest dokładnie to samo zapytanie na dokładnie tym samym DB. Należy jednak zwrócić uwagę na to, że zwracam ponad 90 000 rekordów, więc różnica była dość oczywista. Może na mniejszych zestawach to nie problem? Nie jestem pewien, jak by to się
skalowało w przypadku
5
Dobra odpowiedź. Właśnie spędziłem 4 tygodnie pracując z LINQ-to-Entities, próbując wbić w to wszystko, zanim wreszcie zdałem sobie sprawę, że potrzebujesz natywnego SQL do takich rzeczy, jak kopiowanie zbiorcze, usuwanie zbiorcze, ultraszybkie usuwanie duplikatów z bazy danych itp. Użyj odpowiednie narzędzie do zadania, nie ma wstydu w mieszaniu natywnego SQL z frameworkiem LINQ to Entities.
Contango,
93

Procedury składowane:

(+)

  • Wielka elastyczność
  • Pełna kontrola nad SQL
  • Najwyższa dostępna wydajność

(-)

  • Wymaga znajomości SQL
  • Procedury przechowywane są poza kontrolą źródła
  • Znaczna ilość „powtarzania się” przy jednoczesnym określeniu tej samej nazwy tabeli i pola. Duża szansa na uszkodzenie aplikacji po zmianie nazwy encji DB i pominięciu gdzieś niektórych odniesień do niej.
  • Powolny rozwój

ORM:

(+)

  • Szybki rozwój
  • Kod dostępu do danych jest teraz pod kontrolą źródła
  • Jesteś odizolowany od zmian w DB. Jeśli tak się stanie, musisz zaktualizować swój model / mapowanie tylko w jednym miejscu.

(-)

  • Wydajność może być gorsza
  • Brak lub niewielka kontrola nad SQL, który produkuje ORM (może być nieefektywny lub gorzej). Może trzeba interweniować i zastąpić go niestandardowymi procedurami przechowywanymi. Spowoduje to bałagan w kodzie (niektóre LINQ w kodzie, niektóre SQL w kodzie i / lub w DB poza kontrolą źródła).
  • Jak każda abstrakcja może wytworzyć programistów „wysokiego poziomu”, którzy nie mają pojęcia, jak to działa pod maską

Ogólny kompromis polega na dużej elastyczności i stracie czasu w porównaniu z ograniczeniem możliwości, ale robieniem tego bardzo szybko.

Nie ma ogólnej odpowiedzi na to pytanie. To kwestia świętych wojen. Zależy również od projektu i twoich potrzeb. Wybierz to, co działa najlepiej dla Ciebie.

AGuyCalledGerald
źródło
47
Nie sądzę, aby punkty dotyczące kontroli źródła były istotne. Schemat bazy danych, procedury składowane, UDF itp. Mogą być i powinny być pod kontrolą źródła.
Lee Gunn
15
+1 zaAs any abstraction can produce "high-level" developers having no idea how it works under the hood
nawfal
3
Uzgodniony, argument kontroli źródła jest niepoprawny. Zawsze przechowujemy nasze skrypty tworzenia bazy danych w svn. Jak możesz nawet utrzymać bazę danych poza kontrolą źródła podczas tworzenia aplikacji bazy danych?
Wout
3
EF nie nadaje się do wysokiej dostępności i wydajności, nie jestem facetem z DBA, ale nie widzę, co oferuje EF, co ułatwia kodowanie.
Jamie,
4
Dlatego rezygnujemy z elastyczności, pełnej kontroli i wydajności w celu „szybkiego rozwoju” i unikamy zmian kodu w przypadku zmian DB. Brzmi dla mnie jak lenistwo.
user2966445,
18

twoje pytanie jest w zasadzie O / RM vs. ręczne pisanie SQL

Używasz ORM lub zwykłego SQL?

Spójrz na niektóre inne dostępne rozwiązania O / RM, L2S nie jest jedynym (NHibernate, ActiveRecord)

http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software

aby odpowiedzieć na konkretne pytania:

  1. W zależności od jakości rozwiązania O / RM, L2S jest całkiem dobry w generowaniu SQL
  2. Zwykle jest to znacznie szybsze przy użyciu O / RM po uruchomieniu procesu
  3. Kod jest również zwykle znacznie staranny i łatwiejszy w utrzymaniu
  4. Prosty SQL oczywiście zapewni większą elastyczność, ale większość operacji O / RM może wykonywać wszystkie zapytania oprócz najbardziej skomplikowanych
  5. Ogólnie proponuję wybrać O / RM, utrata elastyczności jest znikoma
Czarny lód
źródło
@David Dzięki, ale to nie jest ORM kontra SQL. Chcę przejść do ORM i zastanawiam się, na co zainwestować czas w naukę: EF lub L2S (chyba, że ​​są śmieciami w porównaniu do przechowywanych procesów)
BritishDeveloper
1
Zdecydowanie powiedziałbym, że nie są śmieciami w porównaniu z przechowywanymi procesami, a dodatkową korzyścią jest to, że nie masz kodu rozłożonego do bazy danych. Osobiście lubię L2S, ale w tym momencie niewiele zrobiłem z EF i wydaje się, że L2EF go wyprze, więc wybiorę EF. Ponadto, kiedy przejdziesz do Linq, nie wrócisz.
BlackICE
13

LINQ-to-SQL jest niezwykłą technologią, która jest bardzo prosta w użyciu i generuje bardzo dobre zapytania do zaplecza. LINQ-to-EF miał go zastąpić, ale w przeszłości był wyjątkowo niezręczny w użyciu i generował znacznie gorszy SQL. Nie znam obecnego stanu rzeczy, ale Microsoft obiecał migrację całej dobroci L2S do L2EF, więc może teraz jest już lepiej.

Osobiście mam namiętny niechęć narzędzi ORM (patrz moja diatrybę tutaj dla szczegółów), a więc nie widzę powodu, aby sprzyjać L2EF, ponieważ L2S daje mi wszystko czego spodziewać się konieczności z warstwy dostępu do danych. W rzeczywistości uważam nawet, że funkcje L2S, takie jak ręcznie wykonane odwzorowania i modelowanie dziedziczenia, dodają całkowicie niepotrzebnej złożoności. Ale to tylko ja. ;-)

Marcelo Cantos
źródło
1
L2S jest całkiem niezły, ale ma tę wadę, że Microsoft stwierdził, że zasadniczo nie zainwestuje dużo w jego rozszerzenie. Możesz zobaczyć wyniki tego już w najnowszej wersji, która ma tylko kilka poprawek błędów i dodano obsługę typów danych SQL Server 2008.
FinnNk
Zgoda, @FinnNk. To niefortunna rzeczywistość, że używanie L2S jest nieco ryzykowne ze względu na status pariai. Ale jeśli naprawdę całkowicie fobują to na korzyść L2EF, mocno podejrzewam, że istniałaby ścieżka migracji, ponieważ nadal cieszy się nią.
Marcelo Cantos
3
Linq do EF dojrzał i teraz produkuje SQL tak dobry jak L2S (od .NET 4.0). L2EF jest obecnie o wiele ładniejszy niż L2S, ponieważ może przynajmniej aktualizować twój model w miarę zmian DB, czego L2S nigdy nie zrobiłby automatycznie. Podoba mi się również to, że można mapować proste relacje M: M z EF jako relacje bez konieczności posiadania pośredniej jednostki. To sprawia, że ​​kod jest o wiele czystszy.
Dave Markle,
2
Dzięki za aktualizację @Dave. Nie zgadzam się jednak z komentarzem M: M. Schematy, nad którymi pracowałem, prawie zawsze rozwijają dodatkowe atrybuty w tabelach łączenia. Powoduje to zmianę strukturalną w modelu obiektowym, wymagającą wielu przeróbek kodu. Wolałbym od samego początku zająć się relacją pośrednią.
Marcelo Cantos
1

Istnieje zupełnie nowe podejście, które możesz rozważyć, jeśli szukasz mocy i wydajności procedur przechowywanych oraz szybkiego rozwoju, jaki zapewniają narzędzia takie jak Entity Framework.

Wziąłem SQL + na jazdę próbną w małym projekcie i jest to naprawdę coś wyjątkowego. Zasadniczo dodajesz, co równa się komentarzom do swoich procedur SQL, a te komentarze dostarczają instrukcji do generatora kodu, który następnie buduje naprawdę ładną bibliotekę klas obiektowych na podstawie faktycznej procedury SQL. Coś w rodzaju podobnej struktury encji w odwrotnej kolejności.

Parametry wejściowe stają się częścią obiektu wejściowego, parametry wyjściowe i zestawy wyników stają się częścią obiektu wyjściowego, a składnik usługi udostępnia wywołania metod.

Jeśli chcesz korzystać z procedur przechowywanych, ale nadal chcesz szybkiego rozwoju, możesz rzucić okiem na te rzeczy.

Vincent
źródło