•  

    #csharp #programowanie

    ORM yay or nay? Jaki jest teraz najlepszy pod .NET Core?

    •  

      @damyrade: Entity na Core jest taki dobry? Bo przy zwykłym .NET Framework to chyba nHibernate królował? Jak z wydajnością?

    •  

      @Khaine:

      Bo przy zwykłym .NET Framework to chyba nHibernate królował?
      Chyba 10 lat temu

    •  

      @Myrten: No to patrząc po ofertach dużo firm ma do utrzymania systemy sprzed 10 lat xD Ludzie zarzucali Entity że nie był code first bodajże. Nie znam się na ORMach, bo nigdy nie miałem okazji ich używać w pełnej krasie -> w projekcie były procki albo statyczne zapytania, żeby wyciskać maksymalną wydajność. ORMów to tylko używali żeby sobie zmapować kolumny na DTO.

    •  

      @Khaine: efcore jest bardzo spoko, z innych prostych ormow dapper jest bardzo przyjemny jeszcze, roboty StackExchange

    •  

      @Khaine: pełny ORM tylko EF Core. W niektórych przypadkach Dapper, który jednak nie jest pełnoprawnym ORMem.

    •  

      @ghostface: Dapper wygląda na coś w stylu "masz tu wywołaj prockę/zapytanie i zrzutuj mi to co wypluje na taki obiekt". Z grubsza to jest coś co lubię najbardziej, bo skomplikowane rzeczy jednak preferuję trzymać po stronie bazy. Łatwiej je modyfikować i zawsze będą szybsze.

    •  

      @Khaine: EF miał ułatwić pracę a zrobili z tego straszną kobyłę i wdrożenie zajmuje sporo czasu. Lubię dappera ale komercyjnie to chyba wszędzie EF jest ( ͡° ʖ̯ ͡°)

    •  

      @Mazowia: A jak wydajnościowo? EF dużo jest gorszy od np. procki wmontowanej w bazę danych zwracającej tablicę?

    •  

      @Khaine: Tego nie wiem ale jak się dowiesz to daj znać ( ͡° ͜ʖ ͡°)

    •  

      @Mazowia: Musielibyśmy zrobić testy z chłopakami, może kiedyś ( ͡° ʖ̯ ͡°) Ale i tak wolę trzymać skomplikowane rzeczy w bazie, dużo łatwiej to potem poprawiać. Nie trzeba rekompilować programu i robić redeploy. Nawet u klienta na prodzie można poprawić coś z marszu w ten sposób. No i łatwiej równolegle pracować przy tym wszystkim bo np. jeden siedzi w bazie a drugi w aplikacji i nie wchodzimy sobie w paradę.

    •  

      @Khaine: no no... a testowanie tej logiki co zawierasz w prockach? A refaktor? A utrzymanie? Imho zdecydowanie lepiej miec jedno zrodlo kodu z logika biznesowa - kod aplikacji.

    •  

      @lukpep: No, jedno źródło kodu, ciekawe tylko jak będzie chodzić? ¯\_(ツ)_/¯ Nie wiem jak jest teraz z tymi ORMami (dlatego się pytałem) ale ostatni raz jak chłopaki podglądali profilerem co ORM generuje za zapytania to przestali ich używać, bo to się nie nadawało do niczego innego niż pod CRUD dla stronki o kotkach i pieskach, a nie mielenie terabajtów danych. Ale może się poprawiło coś od tego czasu, bo to było z 2-3 lata temu.

      testowanie tej logiki co zawierasz w prockach

      Tak szczerze powiedziawszy, to nie do końca jestem fanem testów. W żadnym projekcie przy którym pracowałem ich nie było i każdy z nich działa jak należy -> jeśli oczywiście trzymało się pewnych zasad aby nie komplikować rzeczywistości i pilnować prostoty. Testów trzeba potem pilnować cały czas jak już się je zrobi, więc to jest niby mniej roboty a w praktyce może być więcej. A w zamian możesz dostać iluzję bezpieczeństwa - bo to że test jednostkowy przeszedł nie znaczy, że jak się wszystko poskłada do kupy to nadal będzie dobrze. Różne artykuły na ten temat czytałem i stanowisko odnośnie testów jest mocno kontrowersyjne. Ja uważam, że to jest przede wszystkim narzędzie do łechtania PMów po jajkach w dużych firmach, bo wtedy im ładnie się pokazuje, ze 100% wszystko działa, jest super - można klientowi pokazać i dupsko jest kryte. A jak jest w praktyce to już różnie bywa ¯\_(ツ)_/¯ W bardzo dużych projektach może mieć to większe znaczenie, ale tam gdzie da się to okiełznać umysłem nie widzę potrzeby.

      A refaktor?

      Nie da się refactorować kodu procedur SQL? ( ͡º ͜ʖ͡º) Nawet łatwiej jest, bo ja refaktoruję C# a kolega siedzi obok w SQLu i nie wchodzimy sobie w paradę. Minus taki, że trzeba znać dwa języki a nie jeden -> ale SQL + rozszerzenia trzeba znać, żeby wiedzieć czy ORM nie robi nam jakiejś optymalizacyjnej masakry w zapytaniach. Więc używasz ORMa i jeszcze potem się może okazać, że musisz z niego zrezygnować bo nie spełnia wymogów wydajnościowych albo za gruba rzeźba i wracasz znowu do bazy...

      A utrzymanie?

      A utrzymanie jest zazwyczaj łatwiejsze niż z rekompilowaniem całego programu i robieniem deploya w momencie jak jest jakaś literówka w procedurze. Można wejść klientowi na serwer i po prostu poprawić. Oczywiście gdy mamy taką możliwość frywolnego grzebania w bazie, bo jak nie mamy to może być dużo gorzej. No ale tam gdzie do tej pory pracowałem jakby przy każdej pierdole musieli robić deploy, to by klienci powariowali.

      Imho zdecydowanie lepiej miec jedno zrodlo kodu z logika biznesowa - kod aplikacji.

      No ale w tym wypadku mamy tak, że logika biznesowa jest generalnie albo po stronie frontendu - liczona u klienta, albo po stronie bazy danych. Backend sam w sobie nic nie liczy, tylko przerzuca dane z bazy na front i z frontu na bazę. Ktoś tak zrobił, to tak szybciej działało i wymagało to znacznie mniej zabawy - bo baza danych jest po prostu lepsza w mieleniu danych i mniej się trzeba nakombinować z optymalizacją. Baza danych ma swoje joby, eventy i inne gówna, i sama sobie reorganizuje dane zgodnie z potrzebą. No tam gdzie do tej pory to widziałem, to zdecydowanie zdawało to egzamin.

    •  

      @Khaine:

      Ale może się poprawiło coś od tego czasu, bo to było z 2-3 lata temu

      Ja robie crudy o pieskach i kotkach co prawda ale nic nie stoi na przeszkodzie zeby w razie jakies zapytanie ze strony ORMa jest malo wydajne go wspomoc nawet raw SQLem.

      bo to że test jednostkowy przeszedł nie znaczy, że jak się wszystko poskłada do kupy to nadal będzie dobrze

      oczywiscie ze nie - dlatego sa testy integracyjne, E2E itp. Ale ok - zgodzmy sie ze mamy inne podejscie do testow po prostu.

      Nawet łatwiej jest, bo ja refaktoruję C# a kolega siedzi obok w SQLu

      I za chwile kod aplikacji i jej modele nie ma za wiele wspolnego z modelami w bazie danych. Jezeli to tylko mozliwe to modele powinny byc zgodne na poziomie koncepcji. Wspominasz o literowce w SQL i ze latwo mozna poprawic - tylko ze wlasnie gdyby to byl wspolny code base i praca z modelami domenowymi to tej literowki by nie bylo w ogole i nie byloby co poprawiac.... A co z wersjonowaniem schematu bazy? I logiki biznesowej w procedurach skladowanych?

      No ale w tym wypadku mamy tak, że logika biznesowa jest generalnie albo po stronie frontendu - liczona u klienta, albo po stronie bazy danych

      oryginalnie - musze przyznac. Po co Wam wrecz backend? driver do bazy do frontu i jedziecie ;-)
      Skoro mowimy o jakiejs logice biznesowej to znaczy ze takowa macie - a skoro zawarta jest w bazie to co zostaje w modelach domenowych? Sa workami na propertiesy?

      Jaka to domena w ogole ta aplikacja z ciekawosci? Moze jakis data mining i niepotrzebnie pisze o modelach domenowych itp - a wszystko sie sporowadza do wyciagania danych ;)

    •  

      oczywiscie ze nie - dlatego sa testy integracyjne, E2E itp. Ale ok - zgodzmy sie ze mamy inne podejscie do testow po prostu.

      @lukpep: Ja jeszcze nie widziałem projektu w którym bym czarno na białym zobaczył, że testy coś pomogły. Rzeczy w których do tej pory robiłem były wydajnościowo wymagające, ale stosunkowo proste same z siebie, więc te testy niewiele by pomogły. Inna sprawa, że ciężko by je nawet było wmontować, bo tak średnio się środowiska do tego nadawały. Jak będziemy robić coś nowego to staram się już robić z testami żeby zobaczyć czy faktycznie coś to da, czy przy takiej skali skomplikowania projektu to jest armata na muchy i strata czasu. No w każdym razie mam przykłady z życia, że da się bez tego żyć i de facto ułatwia to modyfikowanie -> bo nie martwimy się testami tylko zmieniamy co potrzeba i tyle.

      I za chwile kod aplikacji i jej modele nie ma za wiele wspolnego z modelami w bazie danych.

      No nie ma. Nigdy nie miał być 1:1. Backend dostaje tylko wycinek rzeczywistości z tego co siedzi na bazie danych, procka zwraca to co jest potrzebne - wiele z tego to są metadane na potrzeby obliczeń wewnętrznych bazy danych. My nie chcemy zwracać wszystkiego, bo to by cholernie drogo kosztowało w czasie i transferze, procka wycina to co potrzeba i tylko tyle oddaje. To co mamy w backendzie i frontendzie to model uproszczony, zawierający tylko dane które użytkownik jest w stanie interpretować.

      A co z wersjonowaniem schematu bazy? I logiki biznesowej w procedurach skladowanych?

      System kontroli wersji YOLO ¯\_(ツ)_/¯ Akurat tutaj tak wyszło, bo ktoś nie pomyślał o kontroli wersji procedur. W poprzedniej robocie mieliśmy specjalne skrypty SQL w których trzymaliśmy wszelkie zmiany, żeby dało się sprawdzić kto, kiedy i co zmieniał.

      oryginalnie - musze przyznac. Po co Wam wrecz backend? driver do bazy do frontu i jedziecie ;-)

      Szczerze, to nie było opcji z niego zrezygnować bo to Silverlight ;) Ale taka warstwa i tak się może przydać na wszelki wypadek -> zawsze można tam coś awaryjnie wsadzić w razie W, ale z tego co do tej pory widziałem to nic poza przerzucaniem z ręki do ręki ten backend nie robi. Zwraca tylko xappa (czyli wwwroot) a potem przerzuca requesty uprzednio przerabiając je na DTO już bardziej zjadliwe dla frontu. Plus jest taki, że teraz gdybyśmy to chcieli przenieść na inną technologię to jedyne co jest do zrobienia to tak naprawdę front. Wpinasz dummy backend, łączysz druty między bazą a frontem i jedziesz. Gdyby ktoś tego nieszczęsnego Silverlighta pisał tak jak mówisz - to musielibyśmy przepisywać wszystko, a tak to tylko front jest problemem, bo backend to puste pudełko które ma zwrócić flaki dla frontu a potem przekładać dane z ręki do ręki. No i gdybyśmy chcieli zmieniać silnik bazy danych - to też trzeba by się było narobić (o ile dany silnik nie jest w stanie zrozumieć T-SQL), ale coś za coś. To jest dobre rozwiązanie jak wiesz, że:

      1. Potrzebujesz max wydajności przetwarzania danych.
      2. Chcesz aby dane reorganizowały się same "automagicznie" - baza zrobi to lepiej i szybciej
      3. Jesteś dosyć mocno przekonany, że będziesz się nadal przytulał z tym samym silnikiem bazy danych i nie będziesz chciał tego przenosić
      4. Masz dostęp do serwerów klienta i dzięki temu możesz mu ładować hotfixy nawet bez jego wiedzy i w trakcie działania aplikacji, nikt nawet nie zauważy że jakiś skrypcik SQL się zmienił

      No to wtedy będziesz miał uniwersalny backend z wystającymi drutami na który możesz zapiąć cokolwiek będziesz chciał - Java, C#, C++, no cokolwiek po prostu z tym będzie działało przy niewielkiej ilości pracy.

      Skoro mowimy o jakiejs logice biznesowej to znaczy ze takowa macie - a skoro zawarta jest w bazie to co zostaje w modelach domenowych? Sa workami na propertiesy?

      Tak. Backend bierze request od frontu w postaci wywołania jakiejśtam metody (GetUsers np.), tłumaczy go po swojej stronie na wywołanie procedury SQL z odpowiednimi argumentami (proc_GetUsers), dostaje odpowiedź od bazy i mapuje ją w taki sposób jak front chciałby to widzieć (UsersDTO) i ten obiekt odsyła -> w tym wypadku po SOAP bo to Silverlight. W REST by po prostu zmontował JSONa z tego. Silverlight ma SOAP zaszyte w sobie wewnętrznie i front łączy się z backendem symulując jakby wywoływanie RPC (czyli mielibyśmy jakieś statyczne UsersService.GetUsers()). Backend jeszcze otrzymuje metadane dotyczące sesji które się czasem przydają przy pompowaniu argumentów do bazy (żeby wiedzieć na ile jakiś użytkownik jest do czegoś uprawniony).

      Jaka to domena w ogole ta aplikacja z ciekawosci? Moze jakis data mining i niepotrzebnie pisze o modelach domenowych itp - a wszystko sie sporowadza do wyciagania danych ;)

      To jest przemiał danych z kilkudziesięciu-kilkuset czujników. Temperatura, wilgotność i nie tylko. Dane w czasie puchną cholernie szybko (bo to są także dane historyczne które użytkownik chce przeglądać) i jest ich bardzo dużo, mówimy o setkach gigabajtów albo o terabajtach. Procedury pozwalają bazie robić sztuczki optymalizacyjne przez co zapytania będą zapewne szybsze niż montowanie mu ręcznie sklejonych selectów za każdym razem + te dane jeszcze w momencie pobierania są przetwarzane wewnętrznie w pętlach z jakimiś podzapytaniami itd. No droga operacja której nie wykonasz zwykłym selectem. Backend musiałby pobrać dużo, duuuużo więcej danych niż by chciał odesłać, a szybciej od bazy danych tego i tak nie zmieli. Trzeba by się było namęczyć, myśleć czy to wszystko jest odpowiednio zoptymalizowane itd. A baza? Baza sobie skompiluje procedurę, zoptymalizuje to wpizdu tak jak lubi i masz to w dupie ¯\_(ツ)_/¯ Jak tylko nie piszesz krzywych selectów żeby baza miała problemy dobierać sobie dane po kluczach głównych to będzie dobrze.