Pojedynek ORM

0

W pracy zabieramy się za nową aplikację. Urządzenia końcowe <-> REST <-> DAL <-> ORM.

Do teraz używaliśmy Entity Framework. Jednak jest dużo głosów, że jest do bani i zastanawiamy się nad alternatywami np. NHibernate. Czy ktoś używa komercyjnie? Czy są jakieś przewagi nad?

10

IMHO, Entity Framework do niczego się nie nadaje, nawet do bani.

NHibernate:

  • Operuje na abstrakcjach, nie implementacjach. Głównym tworem jest ISession, który można bezpośrednio mockować i używać w testach. Nie tak jak w EF, który wymaga opakowania Contextu we wrapperository, żeby jakiekolwiek testowanie było możliwe.
  • Cache drugiego poziomu (jedno dla wszystkich session w aplikacji). W EF niemożliwe nawet do zaimplementowania, ze względu na brak fabryki dla Contextów.
  • Kontrola nad generowanym kodem SQL. NH pozwala chociażby na wybór typu joina, EF zawsze robi left.
  • Rozszerzalność - NHibernate ofertuje ponad 30 zdarzeń dotyczących operacji na encjach (każda crudowa operacja w wersji pre i post oraz specjalne zdarzenia dla kolekcji) dzięki czemu wystarczy się podpiąć i wykonać jakąś logikę. EF dla porównania oferuje dwa zdarzenia.
  • Filtry - globalny where dla danego typu encji. W EF niby też jest coś podobnego, ale nie bardzo używane.
  • Generatory pozwalają NHibernate na ustawienie ID po stronie aplikacji, dzięki czemu zapis grafu obiektów nie wymaga ciągłego odpytywania bazy o ostatnio wstawione ID.
  • Wsadowe wstawianie danych do bazy. W EF niemożliwe do zaimplementowania ze względu na brak generatorów ID.
  • Wsparcie dla leniwych właściwości (właściwości, nie całych obiektów).
  • Wsparcie dla różnych typów kolekcji: list, bagów, setów, słowników.
  • Wsparcie dla różnych typów kolumn dla optimistic concurrency (data, int, timestamp...) EF wspiera tylko timestamp albo wszystkie kolumny.
  • Obsługa future queries - kilka zapytań w ramach jednego UoW można wysłać do bazy jednocześnie. (Np. zapytanie o stronę do grida oraz o liczbę wszystkich rekordów w tabeli.)
  • Możliwość generowania zapytań na podstawie nazw właściwości. EF uznaje tylko wyrażenia lambda, czyli jak UI prosi o sortowanie wg nazwy kolumny grida, to nie można tego po prostu przekazać do EF.
  • Pozwala na definiowanie wyliczanych właściwości tłumaczonych na kod SQL. Dzięki temu można np. dla pozycji faktury zdefiniować sobie wartość TotalPrice jako ItemCount * ItemPrice i używać jej w zapytaniach: .Where(x => x.TotalPrice > 5.0). W EF oczywiście niemożliwe.

Pozostaje też kwestia przyzwoitości - jak można używać czegoś, co nie jest zaprojektowane w zgodzie nawet z SRP? W EF jeden obiekt trzyma konfigurację ORMa i UoW, w NH wszystko to jest mądrze podzielone na trzy obiekty (ten trzeci to fabryka UoW).

Ach, żeby nie było, że EF nie ma żadnych zalet. Ma jedną - designer, który pozwala w kilka sekund wygenerować model na podstawie już istniejącej bazy danych. To znacznie przyspiesza pracę, gdy do już istniejącej bazy danych chcemy zrobić jakąś prostą aplikację i nie zależy nam na architekturze, wydajności, itp.

Ale - ponieważ to jest dobre - to w nowej wersji nie będzie. :D

1

A czy ktoś może ustosunkować się do tego co tutaj jest napisane? http://elearning.pwste.edu.pl/blogjw/2-orm
Jak to tak naprawdę jest? Artykuł jest już dość stary ale... czy native SQL to już właściwie przeszłość i teraz wszyscy korzystają z ORM? Czy jednak jest to przerost formy nad treścią?

Czemu pytam? Mam obsługę native SQL dość dobrze opanowaną w swoich projektach i może warto byłoby się zainteresować innym podejściem. Jak wiele razy pisałem - nie programuję zawodowo w sensie komercyjnym ale jednak piszę w swojej pracy aplikacje, które naszą firmę mają jakoś tam wspomagać. Coraz więcej słyszę o ORM i się zastanawiam czy by tego w kolejnym projekcie nie wykorzystać...

Rozwijam się tak jak sam chcę, bo wszystkie moje aplikacje w firmie to moja własna inicjatywa i... nie mając nikogo nad głową, kto by dyktował mi technologię po prostu pytam. :)

0

Od ORM nie ma ucieczki, ale czasami dobrze jest wstępnie przygotować dane już w bazie. Zamiast robić zapytanie bezpośrednio w kodzie można np. skorzystać z widoku czy procedury przechowywanej, które zwrócą mniejszą paczkę danych. Niestety spotykam się często z programami, które niby przeszły testy, ale w produkcji się zamulają. Jak się później okazuje program był testowany na bazie zawierającej kilkaset rekordów, a na produkcji były kilkaset tysięcy i to co w testach trwało sekundę na produkcji trwa 30s

5

Koleś tam chyba chce udowodnić, że ORM w Pythonie są do bani. No i może ma rację, a może nie. Autor chyba nie do końca rozumie do czego ORMy służą, skoro nie wie nawet, że na podstawie definicji klas można wygenerować strukturę bazy danych.

ORMów używa się, bo pozwalają na przyspieszenie procesu tworzenie aplikacji. Nie trzeba tracić czasu na pisanie i debugowanie pełnego literówek SQL i mapowanie pobranych danych na obiekty, bo ORM robi to za nas. Dlatego nie używanie ORM to okradanie siebie z czasu bądź klienta z pieniędzy.
Ale ORMy to nie są uniwersalne narzędzia do każdego zastosowania. Są miejsca, w których się nie sprawdzają - np. hurtowy upload danych z pliku CSV do bazy - w tym celu istnieją lepsze narzędzia, i zaprzęganie do tego ORMa nie ma sensu. Kod SQL generowany przez ORMy też nie jest doskonały, często ma niepotrzebne podzapytania, złączenia, i inne cechy negatywnie wpływające na wydajność. Poza tym, ORMy działają na obiektach, więc np. jeśli chcesz coś z bazy usunąć, musisz to najpierw wczytać. Dla jednego obiektu nie ma problemu, ale przy tysiącu obiektów usuwanych na raz wg jakiegoś kryterium, już robi się absurd - w takim przypadku lepiej napisać procedurę składowaną i ją wywołać z aplikacji.
Ale wiele kodu SQL, na pewno ponad 90% można dzięki ORMom uniknąć. Zarówno w prostych jak i skomplikowanych projektach.

0

@somekind Wiesz... teraz robiłem sobie po prostu singletona, który w ramach całego projektu obsługiwał mi bazę danych w oparciu o native SQL, a w modelach miałem odwzorowane tabele z bazy danych na klasy (jeden do jednego) np:

Tabela..

// Pseudo-kod:
table user {
    int id;
    varchar[15] username;
    varchar[25] name;
    // etc...
}

...była jednym z modeli czyli klasą:

class UserModel {
    public int Id { get; set; }
    public string Username { get; set; }
    public string Name { get; set; }
}

Taki singleton był dla mnie bardzo wygodny, bo obsługiwał mi cały silnik bazy danych z jednej instancji w całym projekcie.
To teraz dla mvvm taki model to już nie będzie po prostu prosta klasa z własnościami i paroma metodami, tylko cała logika przejdzie z native SQL'a do tegoż modelu, obsłużona przez ORM?

PS: tak sobie myślę... mogę o tym poczytać w Internecie, pewnie... ale jestem ciekaw stricte Waszego zdania, bo trochę Was już znam :)

0
somekind napisał(a):

Ale - ponieważ to jest dobre - to w nowej wersji nie będzie. :D

NIe będzie designera do EF? MS strzela sobie w stopę chyba jak tak. EF był właśnie dlatego prostszy do ogarnięcia, że szybko można było wyklikać coś działającego, łącznie z przejrzystym diagramem bazy (no, powiedzmy że przejrzystym jeśli nie ma tam 500 tabel a 5 albo 10).

0

@XXYY To tak samo jak usunęli z serwera Windows 2012 w zarządzaniu GPO możliwość wpisania zaufanych stron i blokowania całej reszty. W serwerze 2008 mogłem sobie powpisywać, na które strony chcę ludzi wpuszczać prostym formularzem. Wpisywało się adresy, kolportowało się to przez polisy w całym AD i działało. Teraz tego już nie ma w GPO. Taka fajna funkcjonalność - usunięta.

Tłumaczyli to tym, że "nooo... tak zrobiono, bo teraz to przeniesiono na inny poziom abstrakcji, bo inny produkt tym będzie zarządzał etc..." - masakra, strasznie nam tego w pracy brakuje.

0

No cóż, wiele posunięć MS ciężko zrozumieć. A co komu np przeszkadzał generator instalatorów w Visual Studio? Można było wygenerować prawie całkowicie automatycznie działający instalator, było ClickOnce itd. Usunięto to i jaka alternatywa? Może Wix, ale tu wtyczka do Visuala (oficjalna), nie pozwala nawet na automatyczne dodanie plików (!), można bodajże tylko utworzyć custom action w dll i rozszerzenie do Wixa a cała reszta to dłubanie ręczne w xml-u.

1

Ja jestem zdania że ORM to dobrodziejstwo i w większości przypadków się sprawdza, więc czemu z niego nie korzystać. Jak gdzieś pojawiają się problemy z wydajnością to trzeba się przeprosić z SQL ale w większości przypadków ORM jest dobrym wyborem zamiast czystego SQLa.

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