Entity Framework Method syntax vs Query syntax

0

Cześć,

Jak wiadomo kiedy jest wybór to jest dobrze... Ale kiedy jest za duży wybór to może być różnie. W przypadku zapytań Entity Framework mamy dwa rodzaje składni. I powiem Wam, że czasami query syntax wygląda pięknie... ale czasami jak się na to patrzy i przepisze na method zaczyna wyglądać dużo lepiej. Relacja zachodzi naturalnie również w drugą stronę. Można też mieszać ze sobą style.

No i tutaj rodzi się pytanie: co preferujecie? Ze swojej strony powiem, że zaczynam doceniać query syntax, szczególnie w przypadku kiedy już naprawdę muszę zrobić joina jawnie.

Głosować! ;)

1

Query. Za te potworki z method + lambda powinno być wieszanie za jaja. Np tu: https://stackoverflow.com/questions/44047522/modify-linq-code-add-and-statement-to-join

Za to chyba kastracja się należy. Konia z rzędem kto obejmie rozumem to zapytanie, bez pomocy ide.

0

@Tokarz_: No właśnie dlatego też wybrałem query. Jednak, przynajmniej dla mnie, jest to takie trochę bardziej czytelne podejście. Co to method to dokładnie o taki przykład mi chodziło jak pokazałeś. Wypisz wymaluj. W przypadku query nawet nie trzeba joina pisać tylko przykładowo:

from c in db.Companies
from p in c.Persons.DefaultIfEmpty()

I samoczynnie leci LEFT JOIN. Niestety w EF nie da się wielokroć stosować podejścia: do not join, navigate, ponieważ, w przypadku kiedy w encji mamy kolekcję po której chcemy się joinować, a nie pojedynczy obiekt, zamiast zwykłego joina EF postanowi wstawić nam podzapywanie i wydajność leci na łeb na szyję. Czasami trzeba zrobić joina jawnie, a przypadku składni method to jakaś masakra ;)

ORM nie po to został stworzony żeby było trudniej.

PS: kod, który przytoczyłem jako przykład też pewnie dałoby się uzyskać za pomocą method ale... nawiasy i lambdy...

1

Jak dla mnie, method + lambda i owszem, do prostego filtrowania listy np, typu:

lista.First(x=>x.id == 1) zwróci element, gdzie id jest równe 1. Ale jeśli ktoś pisze takie zapytania jak podałem wcześniej, to chyba tylko po to żeby robić innym na złość.

4

Dla imperatywnego, obiektowego języka jakim jest C# dużo bardziej naturalne jest łańcuchowe wywoływanie metod. Dodatkowe słowa kluczowe tworzące jakiś pseudo DSL udający SQL to tylko śmietnik w języku. Języki programowania powinny być ekspresywne. Mało słów kluczowych i konstrukcji, mało pisania, duże efekty. Wprowadzanie kilkunastu słów kluczowych do języka jest totalnym zaprzeczeniem ekspresywności.
Wywoływanie metod wygląda też w większości przypadków lepiej - query syntax jest zwięźlejsze tylko przy tych nieszczęsnych joinach i w przypadku deklarowania wewnętrznych zmiennych w zapytaniach (let). Tylko, że jeśli trzeba pisać joiny mimo korzystania z ORMa, to chyba coś nie tak jest z mapowaniami.

Poza tym, nie istnieje żaden racjonalny argument za korzystaniem z EF. Jeśli potrzebny jest pełny ORM, to są lepsze rozwiązania. Jeśli chcemy korzystać z istniejącej bazy albo piszemy prostą aplikację, to lepiej sprawdzi się Dapper albo inny mikroORM. Jeśli zaś zależy nam na wydajności, to też lepiej sprawdzi się mikroORM.

3

Tylko, że jeśli trzeba pisać joiny mimo korzystania z ORMa, to chyba coś nie tak jest z mapowaniami.

Pójdę z tym nawet dalej - po stronie kodu w ogóle nie powinno być skomplikowanych zapytań. Jeśli robisz jakieś joiny czy inne kosmosy, to IMHO powinieneś stworzyć funkcję lub widok po stronie bazy danych.

1

@aurel: też tak uważam. Nie mówiąc już o tym jak "piękne" zapytania czasami potrafi wygenerować ORM. Każdorazowe sprawdzanie tego jakie zapytanie poszło do bazy przeczy idei ORM'a. Mam mieć pewność, że poszło dobre zapytanie i kropka. Widok gwarantuje spełnienie tego warunku.

Jak czasami widzę ile podzapytań jest generowanych przez ORM, zamiast zrobić zwykłego joina, to zaczynam wątpić w takie zabawki.

0

@aurel - w ten sposób część logiki biznesowej ląduje po stronie bazy danych. I masz ją wtedy w dwóch miejscach, co już z założenia jest słabe. Kod po stronie bazy danych jest trudniejszy w utrzymaniu, bo jest mniej przejrzysty i cieżej pisze się do niego testy. Zgadzam się, że w pewnych przypadkach nie da się zrobić inaczej, niż przenieść zapytanie do bazy danych, ale są to przypadki wyjątkowe.

@grzesiek51114 - nieważne jak wygląda kod sql, który jest wygenerowany i w związku w tym nie musi go czytać inny programista w celu zrozumienia danego fragmentu logiki. Ważne jest, jak szybko ten kod się wykona. Zapytania idące do bazy danych ZAWSZE powinny być sprawdzone pod kątem wydajności. To, że Tobie wydaje się, że wykona się szybko zweryfikuje tylko rzeczywistość, czyli lektura planu zapytania wykonanego na kopii produkcyjnych danych. Jeśli tworzysz view, to jego użycie również powinno być sprawdzone pod kątem wydajności, bo mogłeś np. pomylić kolejność pól w where i optymalizator zignoruje indeks, albo użyjesz view niezgodnie z przeznaczeniem i w zapytaniu znajdzie się kilka table/index scanów dużych tabel. Sam nie zauważysz różnicy pomiędzy 1ms a 100ms czasu wykonania zapytania, a produkcja obciążona wieloma użytkownikami klęknie albo zacznie płonąć. Twoje zaoszczędzone 15 minut może zabrać kilka godzin pracy administratorom i innym programistom.

0

Czyli co, znów odwieczny spór? Jedni chcą przenosić logikę do bazy danych, a inni twierdzą że to złe

0

@aurel - w ten sposób część logiki biznesowej ląduje po stronie bazy danych.

Musielibyśmy chyba porozmawiać o konkretnych przykładach, bo ja nie widzę tutaj logiki biznesowej. Natomiast tak z doświadczenia, im więcej sqla w twoim kodzie, tym więcej krytycznych błędów wynikających z tego, że ktoś coś zmienił w bazie danych i nie powiedział. Podczas gdy kiedy ten kod jest po stronie bazy danych, to jest jakby nie mój problem.

Np. gdy korzystam z jakiegoś restowego API, i ktoś zrobi zmiany w tym API, to te zmiany nie mają prawa wpłynąć na działanie istniejących klientów. Jak masz breaking changes to podbijasz wersję, żeby nic nikomu nie popsuć. Tak samo uważam, że osoba robiąca zmiany w bazie danych powinna je robić tak, żeby klienci bazy w ogóle tego nie zauważyli. Skomplikowane, wielopoziomowe joiny w kodzie klienta praktycznie to uniemożliwiają. IMHO sposobem na to jest właśnie dodanie pewnej warstwy logiki po stronie bazy.

I masz ją wtedy w dwóch miejscach, co już z założenia jest słabe.

To nie jest z założenia słabe, tak jak powtórzenie walidacji na backendzie mimo walidacji na froncie nie jest słabe. Po prostu czasem lepiej jest zrobić coś, co wydawałoby się złym pomysłem w innym wypadku. Jeśli mam do wyboru skomplikowane joiny w kodzie, albo zrobienie widoku i proste jego wołanie, to raczej wybiorę to drugie.

Zapytania idące do bazy danych ZAWSZE powinny być sprawdzone pod kątem wydajności.

I dlatego wolę, gdy jakieś bajery na bazie robi bazodanowiec, bo się na tym zna. Ja nie jestem specjalistą od bazy i nigdy nie będę. Ja w ogóle nie chcę wiedzieć gdzie są indeksy, a gdzie nie ma - ja chcę tylko moje dane.

1
aurel napisał(a):

Musielibyśmy chyba porozmawiać o konkretnych przykładach, bo ja nie widzę tutaj logiki biznesowej. Natomiast tak z doświadczenia, im więcej sqla w twoim kodzie, tym więcej krytycznych błędów wynikających z tego, że ktoś coś zmienił w bazie danych i nie powiedział.

Nadal pracujesz w WK, że ktoś coś zmienia w bazie danych i nie mówi o tym? ;P We w miarę dobrze zaprojektowanej i napisanej aplikacji każda zmiana w strukturze bazy jest odwzorowywana w zmianie modelu ORM, a logika jest przykryta testami. Jeśli ktoś coś spieprzy, to zwykle albo wywali się kompilacja, albo któryś z testów jednostkowych/integracyjnych.
Im więcej sql w bazie danych, tym mniej "sql" po stronie języka programowania wyższego poziomu. Zatem więcej spaghetti-kodu, bo sql ciężko dzieli się na klasy i metody. Za tem mniej testów lub ich brak, bo sql po stronie bazy danych trudniej się testuje. Sql jest jak assembler, generalnie nie nadaje się do implementacji dużej ilości logiki (z pewnymi wyjatkami).

aurel napisał(a):

Podczas gdy kiedy ten kod jest po stronie bazy danych, to jest jakby nie mój problem.

Ciekawe podejście. Twierdzisz, że lepiej, żeby więcej kodu bylo w tej części systemu, do której się nie dotykasz, bo będziesz mieć mniej pracy. Ale bazodanowiec przecież powie cos dokładnie przeciwnego, będzie chciał mniej kodu w sql, wiecej w C#. Które z was będzie miało rację? Mam wrażenie, że kryterium "to nie będzie mój problem" nie powinno być wyznacznikiem pisania kodu. Kod ma efektywnie spełniać swoje zadanie, a do tego być czytelny i łatwy do testowania. Nie ma tu miejsca na "to nie będzie mój problem", bo za kilka lat okaże się, że utrzymanie tej aplikacji kosztuje tak dużo, że projekt zostanie zarzucony (masz to opisane na początku książki Clean Code). A Ty rok wcześniej zmienisz miejsce pracy i faktycznie tamta aplikacja już nie będzie Twoim problemem. Można i tak ;-)

aurel napisał(a):

Np. gdy korzystam z jakiegoś restowego API, i ktoś zrobi zmiany w tym API, to te zmiany nie mają prawa wpłynąć na działanie istniejących klientów. Jak masz breaking changes to podbijasz wersję, żeby nic nikomu nie popsuć. Tak samo uważam, że osoba robiąca zmiany w bazie danych powinna je robić tak, żeby klienci bazy w ogóle tego nie zauważyli. Skomplikowane, wielopoziomowe joiny w kodzie klienta praktycznie to uniemożliwiają. IMHO sposobem na to jest właśnie dodanie pewnej warstwy logiki po stronie bazy.

Jeśli robisz breaking change w bazie danych, to trochę ciężko będzie nie wpłynąć na istniejace API, kod może mieć wersje, baza danych już nie za bardzo.
Piszesz, że "skomplikowane joiny" w kodzie klienta uniemożliwiają wprowadzenie zmian w taki sposób, żeby klienci bazy tego nie zauważyli. Nie zgadzam sie z Tobą, bo problem jest zupełnie w innym miejscu. Jak sama napisałaś, pomiędzy klientem a bazą masz API, które w razie większych zmian w bazie zwykle zapewni wsteczną kompatybilność. Cienki klient, jakim jest przeglądarka internetowa, nie potrzebuje takiej kompatybilności w ogóle. Dodanie warstwy abstrakcji po stronie danych w postaci np. view albo sp nie zagwarantuje uniknięcia wymuszenia zmian w klientach, spowoduje za to dodanie jeszcze jednej warstwy, którą trzeba utrzymywać - dokumentować zmiany, przykrywać te zmiany testami, wdrażać nowych programistów w działanie. Po co nowa warstwa, kiedy jej zadanie może spełnić warstwa już istniejąca?

BTW "skomplikowane joiny", co to takiego? Sql ma setki miejsc, gdzie można utworzyć potworki, ale joiny moim zdaniem do nich nie należą, są moim zdaniem fajnym sposobem na uproszczenie i pogrupowanie listy warunków z klauzuli where.

3

Ciekawe podejście. Twierdzisz, że lepiej, żeby więcej kodu bylo w tej części systemu, do której się nie dotykasz, bo będziesz mieć mniej pracy. Ale bazodanowiec przecież powie cos dokładnie przeciwnego, będzie chciał mniej kodu w sql, wiecej w C#. Które z was będzie miało rację?

Źle mnie zrozumiałeś. Nie chodziło mi o stosowanie spychologii, tylko o to, by każdy zajmował się swoją częścią systemu. Np. css nie powinien się znajdować na backendzie, nawet jeśli akurat jakiś backendowiec sobie wymyśli, że jak do tych danych doda magicznie css to będzie łatwiej i szybciej. Widziałam backendowców, którzy wciskali w swój kod skrypty jQuery i go niemal na siłę dociskali do wyniku, obrzydliwość. Css/js to nie jest problem backendowca i nie powinien być, nie dlatego, że jest leniwy, tylko dlatego, że narobi syfu.

Tak samo nie lubię widzieć w kodzie fragmentów sql i skomplikowanych zapytań ORMowych. Nie dlatego, że jestem taka leniwa i chcę, żeby ktoś inny się tym zajął, tylko dlatego, że nie jestem specjalistą od baz danych. Założyłeś, że bazodanowiec powie coś dokładnie przeciwnego. Z mojego doświadczenia - bazodanowcy chętnie biorą kod do siebie, jeśli też uważają, że to akurat powinno być po stronie bazy. Nie wiem, jak go organizują i testują, bo ja się zajmuję czym innym. Za to bazodanowcy zajmują się właśnie tym, by dane były sensownie zorganizowane, indeksy ponakładane gdzie trzeba i żeby listowanie różnych rzeczy bazy danych nie zajeżdżało.

Zatem więcej spaghetti-kodu, bo sql ciężko dzieli się na klasy i metody. Za tem mniej testów lub ich brak, bo sql po stronie bazy danych trudniej się testuje. Sql jest jak assembler, generalnie nie nadaje się do implementacji dużej ilości logiki (z pewnymi wyjatkami).

Poproszę tu jakichś bazodanowców do dyskusji ;) Ci, których znam (też spoza WK :P), nie uważają swojego kodu za spaghetti-code. Ja natomiast, jak patrzę na te miejsca, gdzie próbowałam jakieś skomplikowany joiny w ormie zrobić, to płakać mi się chce i nie chcę tam wracać.

Jak sama napisałaś, pomiędzy klientem a bazą masz API, które w razie większych zmian w bazie zwykle zapewni wsteczną kompatybilność. Cienki klient, jakim jest przeglądarka internetowa, nie potrzebuje takiej kompatybilności w ogóle. Dodanie warstwy abstrakcji po stronie danych w postaci np. view albo sp nie zagwarantuje uniknięcia wymuszenia zmian w klientach, spowoduje za to dodanie jeszcze jednej warstwy, którą trzeba utrzymywać - dokumentować zmiany, przykrywać te zmiany testami, wdrażać nowych programistów w działanie. Po co nowa warstwa, kiedy jej zadanie może spełnić warstwa już istniejąca?

Jeśli masz API, to jasne, API może spełniać funkcję takiej warstwy. Nie zawsze masz API. Czy zawsze powinno być API?

BTW "skomplikowane joiny", co to takiego?

No daj spokój, nie chodziło mi przecież o to, że join jest skomplikowany :D Nie widziałeś takich potworków w ORMach, gdzie coś, co mogłeś napisać prościutkim sqlem z jednym joinem na maks 100 znaków, w ORMie wymaga 15 linijek dziwnych konstrukcji...? Ja widziałam... aczkolwiek akurat nie w EF, a w Doctrine.

No i na koniec może podkreślę, że ja przecież nie mówiłam o implementowaniu dużej ilości logiki. Mówiłam o pewnej warstwie logiki. Żeby rozstrzygać dogłębniej, musielibyśmy rozmawiać o konkretnych przypadkach, i zastanowić się, czy to już za dużo logiki, czy jeszcze nie za dużo...

1

Kod po stronie bazy danych jest trudniejszy w utrzymaniu, bo jest mniej przejrzysty i cieżej pisze się do niego testy.

Mam przeciwne odczucia. Kod w bazie jest w jednym, spójnym środowisku, dodatkowo to środowisko jest dla takiego kodu naturalne.
Nie wiem co jest trudnego w utrzymaniu kodu po stronie bazy, ale może pracowałem w innych warunkach. Zmiana procedury czy funkcji jest łatwa w realizacji i wystrczy nieco wyobraźni, żeby czegoś nie popsuć.

to jego użycie również powinno być sprawdzone pod kątem wydajności, bo mogłeś np. pomylić kolejność pól w where i optymalizator zignoruje indeks, albo użyjesz view niezgodnie z przeznaczeniem i w zapytaniu znajdzie się kilka table/index scanów dużych tabel.

Strachy na lachy. Jak zmiana kolejności pól w klauzuli where ma ma spowodować zignorowanie indeksu, potrafię sobie ewentualnie wyobrazić jakieś ekstremalne przypadki, których też nie jestem pewien. Widoku można użyć niezgodnie z przeznaczeniem po stronie bazy jak i aplikacji. Dodatkowo nie używając widoku lecz odpowiadającego mu zapytania także możemy popłynąć na skanowaniu dużych tabel czy innym braku optymalizacji.

Wszyscy admini z którymi miałem do czynienia po prostu "uwielbiają" ORMy. Obserwując co potrafi trafić do bazy z takiego ORMa dla niezbyt skomplikowanego zapytania można się naprawdę złapać za głowę. Mi to przypomina html-a tworzonego przez Worda podczas zapisywania doc jako stronę www.

Mam słabe doświadczenie z ORMami, jednak całkiem niezłe z dużymi i złożonymi modelami danych w bazach. W dużej bazie gdzie niebanalne zapytania są na porządku dziennym ORM nie ma szans sobie poradzić w kwestii wydajności swoich zapytań.

Jednocześnie zdaję sobie sprawę z zalet ORMów, coraz bardziej mnie intrygują. Nie są jednak w stanie w 100% zastąpić SQL, jak się niektórym wydaje, nie wszędzie się nadają.

1
hyde napisał(a):

Mam przeciwne odczucia. Kod w bazie jest w jednym, spójnym środowisku, dodatkowo to środowisko jest dla takiego kodu naturalne.
Nie wiem co jest trudnego w utrzymaniu kodu po stronie bazy, ale może pracowałem w innych warunkach. Zmiana procedury czy funkcji jest łatwa w realizacji i wystrczy nieco wyobraźni, żeby czegoś nie popsuć.

Jak piszesz testy do logiki biznesowej w SQL i jak długo się one wykonują?

Wszyscy admini z którymi miałem do czynienia po prostu "uwielbiają" ORMy. Obserwując co potrafi trafić do bazy z takiego ORMa dla niezbyt skomplikowanego zapytania można się naprawdę złapać za głowę. Mi to przypomina html-a tworzonego przez Worda podczas zapisywania doc jako stronę www.

No, jeśli ktoś źle używa ORMów, albo co gorsza ich nadużywa, to generuje takie kwiatki.
Niestety fanatycy ORMów zazwyczaj nie zdają sobie nawet sprawy z istnienia czegoś takiego jak SQL Profiler, więc nie potrafią sprawdzić jak ich magiczny kod w ORM przekłada się na SQL.

Mam słabe doświadczenie z ORMami, jednak całkiem niezłe z dużymi i złożonymi modelami danych w bazach. W dużej bazie gdzie niebanalne zapytania są na porządku dziennym ORM nie ma szans sobie poradzić w kwestii wydajności swoich zapytań.

Ale też nie ma takiego zamiaru. Ideą ORMów jest ułatwienie i przyspieszenie tworzenia aplikacji, a nie wydajność po stronie bazy.

0

Korzystałem z Hibernate/JPA (Java) i moje doświadczenie takie że ORM są świetne do edycji, usuwania i dodawania nowych danych, do czytania w prostych przypadkach OK, ale w takich sytuacjach bardzo dobrze się nadają natywne zapytania SQL

0

@somekind:
Nie piszę testów dla SQL/T-SQL. Niby się da ale to raczej egzotyka. SQL/T-SQL to nie Java, C# etc., nie wszystko należny robić analogicznie. Co do reszty Twojego posta, to chyba się zgadzamy, odnoszę wrażenie, że napisałeś to samo co ja tylko inaczej.

1

Nie piszę testów

#samozaoranie

0

@hyde - w takim razie jak sprawdzacie, czy aplikacja działa?

0

@scibi92:
Miło że się samozaorałeś:)
A na poważnie, unit testy w SQL to raczej egzotyka. Być może się to zmienia w nowszych projektach, ja to raczej siedzę w tych mocno leciwych. Jednocześnie bywam na różnych spendach i konferencjach dotyczących SQL i temat unit testów w SQL to nie jest coś popularnego. W 2015 na SQLDay byłem na sesji poświęconej unit testom, na początku sesji padło pytanie kto używał unit testów w SQL Server, nie wiem czy podniosło ręce kilka osób czy może nawet nikt.
@somekind
Ja sprawdzam tak, że uruchamiam, bo tak mogę. Ale ja jestem z innego świata z antycznych technologii, jeśli chodzi o klienta aplikacji.

Doskonale wiem jaką role odgrywają testy we współczesnych technologiach, ale są tez inne technologie niż Java/C#/Python etc.

0
aurel napisał(a):

Zatem więcej spaghetti-kodu, bo sql ciężko dzieli się na klasy i metody. Za tem mniej testów lub ich brak, bo sql po stronie bazy danych trudniej się testuje. Sql jest jak assembler, generalnie nie nadaje się do implementacji dużej ilości logiki (z pewnymi wyjatkami).

Poproszę tu jakichś bazodanowców do dyskusji ;) Ci, których znam (też spoza WK :P), nie uważają swojego kodu za spaghetti-code. Ja natomiast, jak patrzę na te miejsca, gdzie próbowałam jakieś skomplikowany joiny w ormie zrobić, to płakać mi się chce i nie chcę tam wracać.

To tylko kwestia umiejętności pisania czytelnego kodu wyyrażającej się w dobrym nazewnictwie i dzieleniu kodu na mniejsze fragmenty (dla ORM vide expressions). Wygenerowany sql nas nie obchodzi, może być brzydki jeśli tylko zwraca prawidłowe wyniki i wykonuje się szybko. To pierwsze musi być weryfikowane w testach integracyjnych, to drugie poprzez uważną lekturę planu zapytania wykonanego na produkcyjnej ilości danych.

Jak sama napisałaś, pomiędzy klientem a bazą masz API, które w razie większych zmian w bazie zwykle zapewni wsteczną kompatybilność. Cienki klient, jakim jest przeglądarka internetowa, nie potrzebuje takiej kompatybilności w ogóle. Dodanie warstwy abstrakcji po stronie danych w postaci np. view albo sp nie zagwarantuje uniknięcia wymuszenia zmian w klientach, spowoduje za to dodanie jeszcze jednej warstwy, którą trzeba utrzymywać - dokumentować zmiany, przykrywać te zmiany testami, wdrażać nowych programistów w działanie. Po co nowa warstwa, kiedy jej zadanie może spełnić warstwa już istniejąca?

Jeśli masz API, to jasne, API może spełniać funkcję takiej warstwy. Nie zawsze masz API. Czy zawsze powinno być API?

Uważam, że zwykle tak. Komunikacja aplikacji znajdującej się u klienta bezpośrednio z bazą danych tworzy całą serię problemów, np. zapis do plików, wysyłanie maili, tworzenie testów. A z pośrednictwem API baza danych jest odpowiedzialna za wydajne CRUD danych, a logika jest napisana w języku, który ma klasy, interfejsy, metody, modyfikatory dostępu, który pozwala na IoC (i całe SOLID), gdzie deklaracja zmiennej sprowadza się do użycia jednego słowa kluczowego, gdzie nie ma problemu z napisaniem testów jednostkowych, gdzie zmiana nazwy pola zostanie automatycznie uwzględniona we wszystkich miejscach, które się do niego odwołują, gdzie odwołania do nieistniejących elementów spowodują błąd kompilacji.
Dla mnie zejście do SQL jest jak używanie assemblera. Tylko do wąskich gardeł, Używać się go powinno tylko wtedy, gdy ORM jest za wolny albo uniemożliwia daną operację.

BTW "skomplikowane joiny", co to takiego?

No daj spokój, nie chodziło mi przecież o to, że join jest skomplikowany :D Nie widziałeś takich potworków w ORMach, gdzie coś, co mogłeś napisać prościutkim sqlem z jednym joinem na maks 100 znaków, w ORMie wymaga 15 linijek dziwnych konstrukcji...? Ja widziałam... aczkolwiek akurat nie w EF, a w Doctrine.

Widziałem. Powtórzę: czytelność wygenerowanego kodu jest bardzo mało ważna. Ma działać szybko i skutecznie, a to że baza danych poświęci promil czasu więcej na sparsowanie danych jest pomijalne.

No i na koniec może podkreślę, że ja przecież nie mówiłam o implementowaniu dużej ilości logiki. Mówiłam o pewnej warstwie logiki. Żeby rozstrzygać dogłębniej, musielibyśmy rozmawiać o konkretnych przypadkach, i zastanowić się, czy to już za dużo logiki, czy jeszcze nie za dużo...

Masz rację, natomiast pewne rzeczy zwykle lepiej jest robić zawsze w pewien określony sposób (stąd się wzięły wzorce projektowe). Dlatego można generalizować, że zwykle lepiej umieszczać logikę aplikacji w miejscu, które pozwoli tę logikę łatwiej utrzymać.

0
hyde napisał(a):

Kod po stronie bazy danych jest trudniejszy w utrzymaniu, bo jest mniej przejrzysty i cieżej pisze się do niego testy.

Mam przeciwne odczucia. Kod w bazie jest w jednym, spójnym środowisku, dodatkowo to środowisko jest dla takiego kodu naturalne.
Nie wiem co jest trudnego w utrzymaniu kodu po stronie bazy, ale może pracowałem w innych warunkach. Zmiana procedury czy funkcji jest łatwa w realizacji i wystrczy nieco wyobraźni, żeby czegoś nie popsuć.

Jeśli system jest duży, a Ty poruszasz się w nim od kilku miesięcy, to nie masz pojęcia o wielu aspektach jego działania. Zmiana działania części systemu może w nieprzewidywalny sposób wpłynąć na inną część systemu, o której nie będziesz wiedział nie tylko jak działa, ale nawet, że istnieje. Dlatego właśnie pisze się testy - aby uniknąć regresji. Jesli coś zepsujesz, to któryś z testów powinien się wywalić, jeśli tak się nie stanie, to prawdopodobnie nic nie zepsułeś i możesz swoją zmianę przykryć kolejnym testem.

to jego użycie również powinno być sprawdzone pod kątem wydajności, bo mogłeś np. pomylić kolejność pól w where i optymalizator zignoruje indeks, albo użyjesz view niezgodnie z przeznaczeniem i w zapytaniu znajdzie się kilka table/index scanów dużych tabel.

Strachy na lachy. Jak zmiana kolejności pól w klauzuli where ma ma spowodować zignorowanie indeksu, potrafię sobie ewentualnie wyobrazić jakieś ekstremalne przypadki, których też nie jestem pewien. Widoku można użyć niezgodnie z przeznaczeniem po stronie bazy jak i aplikacji. Dodatkowo nie używając widoku lecz odpowiadającego mu zapytania także możemy popłynąć na skanowaniu dużych tabel czy innym braku optymalizacji.

Oczywiście, że możemy. A skoro potencjalne problemy z wydajnością są podobne niezależnie od tego, czy używasz ORM, czy bezpośrednio SQL, to i tak musisz sprawdzić plan zapytania. Dlatego moim zdaniem zwykle lepiej jest pisać kod w języku, który ma szereg przewag nad SQL: lepszą czytelność, obiektowość, łatwe tworzenie testów, spełnienie SOLID. Podkreślam - zwykle, bo zawsze zdarzają się wyjątki.

Wszyscy admini z którymi miałem do czynienia po prostu "uwielbiają" ORMy. Obserwując co potrafi trafić do bazy z takiego ORMa dla niezbyt skomplikowanego zapytania można się naprawdę złapać za głowę. Mi to przypomina html-a tworzonego przez Worda podczas zapisywania doc jako stronę www.

To nie ma znaczenia. Powtórzę co pisałem w poprzednim poście: wygenerowany sql ma się wykonać małym kosztem i ma zwrócić prawidłowe dane. nie musi być czytelny, bo nikt go czytać nie będzie. Dopiero tam, gdzie ORM sobie nie radzi, siada gościu, który zna dobrze bazę danych i pisze ładny i optymalny sql.

Mam słabe doświadczenie z ORMami, jednak całkiem niezłe z dużymi i złożonymi modelami danych w bazach. W dużej bazie gdzie niebanalne zapytania są na porządku dziennym ORM nie ma szans sobie poradzić w kwestii wydajności swoich zapytań.

Masz słabe doświadczenie z ORM, ale wiesz, że na pewno sobie nie poradzi? ;-) Ja przez ostatnie dwadzieścia lat napisałem kilometry sql i tysiące zapytań w ORM i twierdzę, że dobry ORM radzi sobie z większością przypadków. Nie będę polemizować z faktem, że istnieją miejsca, gdzie ORM nie da rady wykonać danej operacji albo gdzie będzie zbyt wolny, jednak są to wyjątki. Zwykle nie ma potrzeby schodzenia do poziomu SQL.

0

@ŁF:
Zasadniczo to ja się z Tobą zgadzam. Ty mówisz o przypadkach typowych a ja o tych szczególnych.
Ja piszę zapytania od 10 lat, a to że mam słabe doświadczenia z ORM wynika m. in. z tego, że pisze je w warunkach gdzie ORM nie dał rady. Z drugiej strony wynika to z faktu używania głównie niszowej technologii bez ORMów.
Przecież nie utrzymuję dużego systemu sam. Są w firmie ludzie od ORM i od nich wiem, że sobie nie radzi.
No i czytelność SQL, dla mnie to jeden z czytelniejszych języków. Kwestia przyzwyczajenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1