Curiozitate Dapper / EF Core 2

I-am facut unui prieten o aplicatie de nivel mic, cu API in .Net Core 2 si clientul in Angular 8. Problema e ca uneori, raspunsul ajunge destul de greu (se poate vedea in browser/Network/ request in pending, dureaza cateva secunde).

Eliminand ideea de client lent (angular, pachete multe nefolositoare, etc) ramane sa ma gandesc la modul in care fac interogarile in DB. Folosesc EF Core 2 pentru asta. Am citit cateva diferente intre ADO, EF si Dapper …n-as alege ADO pentru faptul ca nu-mi place deloc ideea de lucru cu dataseturi si tabele si imi pare bun doar pentru WPF/WinForms. Am vazut ca multi prefera Dapper pentru ca ar fi mai rapid decat EF. Dar, din datele gasite pe internet, Dapper este mai rapid decat EF 6, rezultatul fiind altul daca il compar cu EF Core 2 (cel din urma fiind mai bun).

Stiu care ar fi diferenta dintre Dapper si EF … cel de-al doilea fiind mai bun doar pentru dezvoltator (reduce timpul foarte mult), iar Dapper castigand timp mai ales in cazul SELECTurilor. Am vazut ca se pot folosi si impreuna, si am zis sa incerc.

Deci, am instalat frumos Dapper, si am modificat aducerea listei pe o entitate (GetAll). Ma obliga (cel putin asa cred eu) sa folosesc repository, scriu un cod enorm (vreo 150 - 200 linii) doar pentru metoda GetAll() pentru ca mai am si cateva joinuri intre tabele, scriu queryuri curate sql (ma ajuta sa-mi perfectionez cunostintele in SQL), 20/30 minute ca timp, ceea ce in EF as fi scris in maxim 3 linii. O parte buna ar fi ca eliberez controllerul de functiile de filtrare si sortare si toate astea se duc in repository, dar …

Nu am tabele uriase, poate in unele cateva sute/mii de linii.

Si intrebarea e … merita sa folosesc Dapper in locul a EF pentru selecturi, in acest caz (tinand cont ca ar fi o munca destul de mare, iar diferenta ar putea fi insesizabila) ?

https://devforum.ro/t/curiozitate-dapper-ef-core-2/10946

Dapper merge pe o alta abordare. nu mai genereaza el sql ci il scrii tu. din 2-3 linii de cod ed core stie sa genereze sql ul si mai face si altele. vezi in sql profiler cand faci un query din ef

nu este mai bun sau mai prost, ci doare are un alt use case.

orice orm adauga un overhead

Auci, stersesem postarea. Pai tocmai din cauza ca trebuie sa scrii tu SQL mi se pare ca pierzi destul de mult timp, plus zeci de linii de cod, queryul trebuie compus pentru ca de obicei în liste ai și filtrare, sortare și paginare. Iar dacă ții neapărat sa scrii SQL și sa’l execuți apoi pt ca e mult mai rapid în felul asta, EF accepta asta, și atunci… Îmi pare ca diferenta o sa fie cam insesizabila. Am testat alaltăieri și Dapper, dar sa lucrez cu ambele… Cel puțin pe acel proiect ma obliga sa’i mai adaug și niște repository uri lângă controller și sa fac injecție apoi… Ceea ce am înțeles ca iar, nu e la fel de rapid ca un ‘using’ :thinking:

“Notice that Entity Framework Core 2’s plain sql commands are almost giving the same result as Dapper(very little difference).”

cred ca raw sql este rapid
nu mai trece prin orm ci se duce direct la baza de date :slight_smile:

curiozitatea mea era daca diferenta asta poate fi sesizata de utilizator, tinand cont marimea bazei de date … maxim 10 tabele, din care doar vreo 3 sa aibe peste cateva sute de linii. Pe langa asta, folosesc multe joinuri (sau Includeuri in ef), astea cred ca trag destul de mult in jos

nu pare a fi sesizabila

mai conteaza si cat de optim scrii query-ul

nu imi pare ca ai o baza de date mare

Problema mea e ca pentru volumul ala mic de date, imi pare ca raspunsul vine destul de tarziu.

baga un profiler in sql server sa vezi ce este cu acel query

executa query-ul cu explan in fata si vezi unde se pierde timp

o sa ma uit. sper sa nu fie din cauza angularului, ca n-am ce-i prea face in cazul asta, decat sa salvez unele date in localStorage :))) merci

Ca o precizare, @horia141 poate stie mai multe despre Dapper :smiley:

Yup, am lucrat cu Dapper vreo doi ani și îl consider super! Dar cumva, în toată cariera mea “web” (3 job-uri până acum), am lucrat numai la proiecte cu micro-ORMs. Ce știu de ORM-uri mari sunt din varii proiecte personale in Django si (majoritatea) vorba de pe net. Așadar am in general o părere proasta despre ele :slight_smile:

Sfatul meu standard aici e:

  • Este esențial să înțelegi bine cum merge sistemul de stocare pe care-l folosești
  • De cele mai multe ori, sistemul este SQL based așa că e bine să știi SQL-ul din produs bine
  • E mai util sa folosești sistemul că atare, decât să speri la vreo interfață generică ce merge pentru toate produsele RDBMS. Common denominator este trist rău, dar fiecare sistem în sine e ft tare
    Ca stare, multe dintre avantajele ORM-urilor nu prea apuca sa se evidențieze. Mai mult încurcă. Și why bother? Baga Mai bine ceva cu un nivel de abstracție mai mic - un MicroORM.
3 Likes

Folosesc ORMs de peste 10 ani in proiecte .NET de diferite dimensiuni. In principal am folosit NHibernate si apoi Entity Framework ca deh, asta e trendul, iar NHibernate nu prea s-a mai dezvoltat.
Dapper nu am folosit, dar am auzit numai lucruri bune despre el.

Din experienta mea, dureaza destul de mult pana ajungi sa stapanesti bine un ORM de acest nivel (NHibernate, EF), iar un ORM nu inlocuieste absolut deloc optimizarile pe care trebuie sa le faci tu, ca programator, pentru problema sau query-ul tau specific.
ORM-ul este fix ceea ce ii spune si numele: Object Relational Mapper, adica a fost inventat pentru ca programatorii sa scrie cod OOP (si) atunci cand acceseaza o baza de date. In plus, relatiile dintre obiecte/entitati sunt mult mai complexe si de mai multe tipuri decat one-to-many sau many-to-many, iar un ORM iti permite sa definesti si controlezi mai bine relatiile dintre entitati.

Facand abstractie de faptul ca orice ORM adauga o mica latenta, pentru ca in fond adauga inca un nivel de abstractizare proiectului, tot din experienta mea pot sa spun ca intotdeauna “problema” este la programator si la cum foloseste acesta ORM-ul respectiv, ci nu la frameworkul ORM in sine.
Poti scrie query-uri peste entitati cu un ORM care sa genereze fix acelasi sql pe care l-ai scrie tu de mana, dar pentru asta trebuie sa intelegi bine ORM-ul respectiv si sa folosesti niste tool-uri (a sugerat cineva mai sus sa pui un Sql Profiler sa vezi exact ce sql se genereaza si sa intelegi de ce se executa asa lent).

Cu toate ca, personal, as folosi un ORM in orice proiect care are ca storage un RDBMS, nu de putine ori a trebuit sa scriu sql pur (views sau stored procedures) pentru a optimiza anumite query-uri. Orice ORM decent iti permite si acest lucru: sa folosesti o procedura stocata acolo unde vrei mai mult control pe sql-ul generat.

In concluzie, nu cred ca problema ta tine de EF in sine, ci mai degraba de cum il folosesti tu pentru query-ul respectiv.

De asemenea, este o aberatie sa spui ca Dapper este mai rapid pe select-uri decat EF sau orice alt ORM. Daca reusesti sa scrii un query in EF (Linq) care sa genereze acelasi sql pe care il scrii tu de mana in Dapper, crede-ma ca acestea se executa in aproximativ acelasi timp (sau diferenta va fi insesizabila si influentata doar de modul in care fiecare ORM functioneaza intern).

Un alt aspect pe care il descoperi abia dupa ce folosesti mult timp un ORM si ajungi sa il stapanesti bine, este ca nu intotdeauna acesta este mai lent decat sql pur (ADO.NET). De ce? Pentru ca un ORM poate face join-uri in memorie, avand 1-2 niveluri de cache (daca sunt folosite, binenteles). Apoi, la unele ORMs mai exista notiuni precum Futures sau Batch Processing, care pot optimiza extrem de mult anumite operatii.

6 Likes

Daca tot suntem la acest capitol, ef foloseste ado net intern ?

Ca in ado net stiu ca mai foloseam clasele SqlConnection, SqlCommand