EF Core vs Dapper

AdamWox
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Jastrzębie-Zdrój
  • Postów:2149
0

Witam.
Piszę z kwestią, która już była parę razy poruszana w pomniejszych wątkach. Moje dwa poprzednie projekty korzystają z EF Core i miałem kilka "gwoździ", które rozwiązywałem na różne, szalone sposoby. Teraz stoję przed dylematem, czy dalej brnąć w EF Core, czy może spróbować oprzeć oprogramowanie na Dapperze, bo akurat Dappera znam. Brak elastyczności w przypadku EF trochę mnie boli, ponieważ tak jak zostało to napisane, w którymś z moich wątków - nie ma ogólnych zapytań SQL. Czyste query można sobie puścić z poziomu tabeli, a nie z poziomu całego contextu. Dapper, z drugiej strony, odstrasza mnie "strukturą" - dapper.contrib nie jest w stanie zapisać generycznych obiektów, trzeba gdzieś trzymać wszystkie stringi z zapytaniami. Takie mam doświadczenia z tymi technologiami. Jak żyć? Co wybrać?

mar-ek1
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 2 godziny
  • Postów:525
4

My w pracy używamy mixu obu - zapis przez EF Core i odczyt zwykle przez Dappera. Tylko mamy osobne klasy do zapisu i odczytujemy to zupełnie innych klas (dokładnie takich jak w danej chwili potrzeba). Powiedzmy, że jest to CQRS (w jakiejś tam podstawowej wersji).
Tylko mamy to podzielone na niewielkie, podzielone na warstwy klasy i metody więc string z sqlem jest jeden w klasie, który robi dokładnie to co ta klasa potrzebuje, a nie, że wszystkie zapytania w aplikacji są wpakowane do gigantycznej klasy statycznej czy coś tego typu.


Szekel
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 3 lata
  • Postów:253
0

To zależy od projektu. Jeżeli masz mały projekt z małą bazą danych to używanie Dappera jest wyciąganiem armaty na wróbla. Przy większych projektach a w zasadzie przy dużych zapytaniach Dapper radzi sobie dużo lepiej niż EF. Najlepiej używać mix tych dwóch. Do małych zapytań EF, do dużych (w sensie obciążających) Dapper.


AdamWox
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Jastrzębie-Zdrój
  • Postów:2149
0

Pytanie teraz co to jest mały projekt? :-) Ogólnie i krótko pisząc - zarządzanie kontraktami na produkty pomiędzy firmami, z bazą plików (pdf, doc, jpg...) powiązanych z kontraktem lub produktem z uwzględnieniem uprawnień dla użytkowników do tych plików. Duży projekt, czy mały?

Szekel
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 3 lata
  • Postów:253
2
AdamWox napisał(a):

Pytanie teraz co to jest mały projekt? :-) Ogólnie i krótko pisząc - zarządzanie kontraktami na produkty pomiędzy firmami, z bazą plików (pdf, doc, jpg...) powiązanych z kontraktem lub produktem z uwzględnieniem uprawnień dla użytkowników do tych plików. Duży projekt, czy mały?

Mały/duży to indywidualna kwestia. Tak samo wielkość bazy też. Aczkolwiek możesz z grubsza oszacować jak duże będziesz miał zapytania w projekcie. Jeżeli znasz schemat bazy to na podstawie use casów możesz z grubsza pokminić ile będzie joinów między tabelami i jak są skomplikowane. Jeżeli schemat jest prosty (Users, Posts, UserRoles, Comments, etc) to EF sobie z tym poradzi. Jeżeli masz pewnie ze 100 tabel i z 10 joinów do zapytania to EF mówi pass.


VA
  • Rejestracja:ponad 7 lat
  • Ostatnio:dzień
2

Jeśli chcesz korzystać z EF i masz problem z jakimś jednym konkretnym zapytaniem to warto się zastanowić nad użyciem procedury składowanej i wykonania jej z poziomu EF. To daje równie mocną elastyczność jak Dapper.

ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:3 dni
3

Czy Dapper ma swój model bazy danych i mechanizm do jego aktualizacji?
Istotną częścią większości ORMów jest mechanizm zapewniający pewien poziom spójności pomiędzy kodem a bazą danych. Jeśli używasz podejścia database first i robisz zmiany w bazie, a potem aktualizujesz model bazy, to większość (jeśli nie wszystkie) zmian wyjdzie na etapie kompilacji. Zmienione nazwy tabel, pól, typów pól, parametry sp itp. To pozwala na zmniejszenie ilości błędów w kodzie (mniejsza regresja), więc jest bardzo dużą zaletą. Niestety cała infrastruktura ORM często zjada dużo zasobów i spowalnia komunikację z bazą danych, a generowane zapytania czasem są dalekie od optymalnych.
Pisanie zapytań bezpośrednio do bazy danych likwiduje ten problem, ale też zabiera kontrolę spójności z bazą danych. Dlatego moim zdaniem w dużych projektach najlepsze jest mieszanie obu podejść, czyli używanie dużego ORM wszędzie, gdzie nie powoduje to wąskich gardeł oraz małego mappera w takich miejscach. Przy małych projektach, gdy łatwiej zapanować nad całym kodem naraz, wybór EF/Dapper moim zdaniem powinno zależeć tylko od wymaganej wydajności.

Pamiętajmy, że w tych czasach słaba wydajność to czasem kwestia dokupienia kilku maszyn/dołożenia kilku procesorów, co zwykle jest tańsze niż dodatkowe godziny pracy programistów albo wkurzeni błędami klienci odchodzący do konkurencji.


JP
Maszyny można dołożyć ale co z licencjami np. na SQL Serwer na Windows + dodatki? Koszty licencji 2-krotnie, albo i lepiej, przekraczają koszty sprzętu.
JU
  • Rejestracja:około 22 lata
  • Ostatnio:24 dni
  • Postów:5042
0

U siebie też robię miks. Zacząłem od EfCore + nHibernate. Ale z nHibernate było duuużo problemów jak na moje założenia (za dużo robi), więc przesiadłem się na Dappera. EfCore jednak używam tylko do standardowych rzeczy (w stylu ogarnianie użytkowników, ról itd). Problem z Dapperem jest tylko taki, że czasem są potrzebne różne zapytania pod różne DBMS. Akurat w moim projekcie używam jednocześnie MSSQL i SQLite, co stanowi wyzwanie w pewnych momentach :) Ale idzie to opanować.

mad_penguin
mad_penguin
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Rzeszów
0
var napisał(a):

Jeśli chcesz korzystać z EF i masz problem z jakimś jednym konkretnym zapytaniem to warto się zastanowić nad użyciem procedury składowanej i wykonania jej z poziomu EF. To daje równie mocną elastyczność jak Dapper.

A co myślisz o używaniu do tego celu widoków? W ten sposób te skomplikowane joiny trzymamy po stronie bazy, ale wciąż możemy wykorzystać EF np. do filtrowania (co w większości przypadków już powinno generować proste query).

VA
@mad_penguin: jasne, można oczywiście użyć widoku
AdamWox
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Jastrzębie-Zdrój
  • Postów:2149
0

Widzę, że większość korzysta z obu rozwiązań. Teraz pytanie w kwestii Dappera i jego "struktury". Przyznaje się, bez bicia, że do tej pory robiłem klasę statyczną Queries i pakowałem wszystkie stringi z zapytaniami tam. Rozwiązanie, które zasugerował @mar-ek1 ma sens, tylko nie wiem, czy dobrze rozumiem. Jako statyczna właściwość modelu?

Kopiuj
public class Product
{
   public int Id {get;set;}
   public string Name {get;set;}

   public static string GetAllQuery = "select * from Products";
   public static string GetByIdQuery = "select * from Products where Id = @Id";
   public static string GetByNameQuery = "select * from Products where Name = @Name";
}
Akihito
U mnie w ex firmie, query daperowe były trzymane w osobnych plikach sql i zaczytwane z nich. Akurat my mieliśmy masakrycznie długie sql po 100-150 linii. Co do zalet tego rozwiązania to jest taka, że visual studio formatuje ci to i koloruje w kolorze sqlowym :)
mar-ek1
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 2 godziny
  • Postów:525
1

Nie trzymam sqla w modelu bo to co jest w bazie może nie mieć nic wspólnego z tym co czytam.
Akurat w naszym przypadku mamy handlery/serwisy, które wyciągają konkretne rzeczy. Jak potrzebuję listę IDków userów z rolą "Tester" to mam klasę, która takie dane wyciąga i mapuje na odpowiednie DTO. Jak potrzebuję z tej samej tabeli wyciagnąć szczegóły aktualnego usera to mam kolejną klasę, która to robi, zwłaszcza, że te dane mogą być np. w 10 tabelach bo na te szczegóły może się składać liczba dodanych do niego projektów, nazwisko przełożonego, data ostatniego logowania i awatar. I w obu przypadkach czytam przypadkiem z tej samej tabeli, ale to są zupełnie inne dane i inne DTO więc i inne query i klasy, które to robią.

Model do zapisu ma tylko to co jest potrzebne do zapisu. Praktycznie nigdy nawet nie zwracamy tego modelu potem.

EDIT/Offtop: Jak widzę "getAll", a potem "getById", "getByName", "getByShoeSize" to mam wrażenie, że coś jest nie tak. Bo kiedy np. potrzebujesz całą tabelę wyciągnać?


edytowany 2x, ostatnio: mar-ek1
WeiXiao
Bo kiedy np. potrzebujesz całą tabelę wyciągnać? wtedy, kiedy jest to słownik ;)
AdamWox
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Jastrzębie-Zdrój
  • Postów:2149
0

Czy to przypadkiem nie jest swego typu overkill robić osobne klasy dla każdego zapytania? Czy znowu czegoś nie rozumiem? Ile masz, w sumie, klas w takim projekcie?

mar-ek1
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 2 godziny
  • Postów:525
5

Nie mam tych klas zbyt dużo bo może ze 20? Tyle ile mam endpointów w API. Po prostu każdy endpoint dostaje dokładnie to czego potrzebuje, w takim formacie jaki chcę, bez nadmiarowych danych albo dziwnych zlepionych struktur.

Dzięki temu jak chcę zmienić strukturę danych w endpoincie A to to zmieniam, a nie zastanawiam się czy nie zepsuję endpointów B, C, D przez to.

Jak poszukasz info o takim podstawowym CQRS na jednej bazie to tam pewnie będzie to opisane lepiej.


edytowany 2x, ostatnio: mar-ek1
AdamWox
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Jastrzębie-Zdrój
  • Postów:2149
0

No ok, myślę, że ma to sens. Mam jeszcze jedno pytanie - bo skoro mam zamiar używać EF + Dapper, to jak to jest w kwestii tworzenia bazy? Czy w takim przypadku też korzystam z code first? Dlaczego ten sposób jest tak popularny? Chodzi o napisanie raz klas i nie trzeba dłubać tabel w Management Studio?

Szekel
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 3 lata
  • Postów:253
0

Dapper nie gryzie się z EF. Dapper robi operacje czystym SQL na bazie a entity framework wymaga spójności modelu dbContextu z bazą. Możesz zastosować cose first bo jest po prostu łatwiejszy i spójny między dwoma systemami (apka i baza). Dłubanie tabel ma to ryzyko że zrobisz rename tabeli i EF tego nie załapie jeżeli nie wprowadzisz zmian w kodzie.


JP
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 miesiące
  • Postów:1065
1

Dbcontext nie wymaga spojnosci z cala baza tylko z tym co ma zmapowane.mozesz mieć kilka dbcontextow w aplikacji i każdy mkze sobie malować po swojemu czesci bazy + jeden DbContext dla całej bazy do migracji.
Co ma dapper, poza wydajnością, czego nie można zrobić w EF?

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)