Generyczne repozytoria- czy to w ogóle ma jakiś sens?

2

@somekind:

tyle hipsterowania, a wystarczyło przeczytać w dokumentacji, że aby inne encje zostały pobrane, to trzeba joina zrobić :(

var entry = context.Entries.Include(x => x.Tags).Single(x => x.Title == entryTitle);

if (_tags.Count > 3) // Ważna logika biznesowa
throw new Exception("XD");

screenshot-20210220091400.png

w tym drugim przykładzie to jakbyś mógł napisać co dokładnie chcesz osiągnąć

1
nobody01 napisał(a):

Test 1) Dlaczego chcesz, żeby ef core (w sumie nawet nie ef core a sama aplikacja) tam rzucił wyjątek, skoro nie zaciągnąłeś _tags?

Bo powinny zaciągnąć się same? W końcu ten wspaniały ORM miał nie mieć problemu z polami.

Jak _tags są częścią agregatu Entry, to powinny być owned types, żeby ef core je zawsze zaciągał.

Czyli jednak jest problem, i trzeba się naginać do ograniczeń ORMa?

Test 2) Potrzebne była Ci kiedykolwiek taka funkcjonalność? Zazwyczaj chyba używa się instancji db contextu per request (scoped).

To nie jest funkcjonalność, ale dołączenie obiektu spoza kontekstu to dość standardowa potrzeba.

WeiXiao napisał(a):

tyle hipsterowania, a wystarczyło przeczytać w dokumentacji, że aby inne encje zostały pobrane, to trzeba joina zrobić :(

Faktycznie, z tym to działa, ale to jest pole, prywatne pole, miało nie być problemów!

w tym drugim przykładzie to jakbyś mógł napisać co dokładnie chcesz osiągnąć

To proste - mieć działającego ORMa. :D

Żeby nie było - ja widzę postęp, spory postęp. To wspaniałe, że już od trzech miesięcy nie trzeba tworzyć klas pośredniczących dla M:N, a chyba od nieco dłuższego czasu nie trzeba mieć dodatkowego Id, więc już można prawie programować obiektowo. Jeszcze jakieś 10 lat i Microsoft wyprodukuje całkiem sprawnego ORMa. Pytanie tylko, jak popularne będą relacyjne bazy danych za 10 lat. ;]

4

@somekind:

Faktycznie, z tym to działa, ale to jest pole, prywatne pole, miało nie być problemów!

czekaj bo czegoś nie łapie, oczekiwałeś że ORM będzie Ci sam z siebie walił jakieś JOINy do innych tabel?

ciekawy pomysł na ubicie wydajności, w NH tam tak wiele dzieje się "pod spodem"?

Fajnie że ten 🌼 wyszedł, bo to tylko kolejny argument ku temu, aby częściej w dyskusjach pokazywać kod, bo kod najlepiej weryfikuje rzeczywistość :)

1
somekind napisał(a):

dołączenie obiektu spoza kontekstu to dość standardowa potrzeba.

Mógłbyś podać przykład?

Czyli jednak jest problem, i trzeba się naginać do ograniczeń ORMa?

Użycie builder.OwnsMany w klasie konfiguracyjnej to naginanie się do ograniczeń ORMa?

a chyba od nieco dłuższego czasu nie trzeba mieć dodatkowego Id, więc już można prawie programować obiektowo

Shadow properties byly już w 2017: https://stackoverflow.com/a/47650462/13172711
W sumie to chyba od wersji 1.1 z 2016? https://csharp.christiannagel.com/2016/11/07/efcorefields/

0

Nie róbmy proszę wojny pomiedzy EF i NH bo nie o tym był temat :)
Może mi ktoś dać odpowiedz czy pobieranie danych z bazy moze opierać się na serwisie któy ma metody typu:

public async Task<User> GetByName(string name)
{
return await context.Users.FirstOrDefaultAsync(u=>u.Name==name);
}

czy jednak tak jest zle i powinno się robić inaczej (jak?)

2

@kalimata: Złe, bo jest bez sensu, gdy przyjdzie wyszukiwać po mailu, to będzie kolejna metoda w interfejsie. Dlatego najlepiej jest ukryć fakt, że użyty ef i po prostu wystawić

T GetByCriteria<T>(Func<IQueryable<User>, T>) // funktor, żeby łatwiej było zarządzać scopem

Come on, queryable są po to żeby korzystać, ani EF nie jest jedyną implementacją która to potrafi przerobić
(
https://github.com/zhurongbo111/ExpressionToWhereClause,
https://github.com/ryanwatson/Dapper.Extensions.Linq,
https://github.com/gambarra/ExpressionExtensionSQL
)

0

@Pixello: czyli w warstwie dostepu do danych można to zrobic tak jak napisałes, a gdzies tam wyzej np wysatawiajac api dla uzywtkownika moge mu ograniczyc ze szukanie jest tylko po mailu?

0

W sensie? Do obsługi endpointów jest OData + ewentualnie AutoMapper.MappingExpression, żeby można było userowi wystawić DTO zamiast obiektu domenowego.

Tam można w regułach ustawić co może konsument robić z którą właściwością

0

@Pixello

Dlatego najlepiej jest ukryć fakt, że użyty ef i po prostu wystawić

jakby coś, to w tym wątku (pierwsze dwie strony) już był poruszany pomysł na przekazywanie drzewek i generowanie z nich SQLa, ale ludzie uznali że to słabe.

bo jest bez sensu, gdy przyjdzie wyszukiwać po mailu, to będzie kolejna metoda w interfejsie. Dlatego najlepiej jest ukryć fakt, że użyty ef i po prostu wystawić

W ogóle ja bym poszedł krok dalej - po co mi jakaś kolejna abstrakcja nad EF Corem?

2
WeiXiao napisał(a):

czekaj bo czegoś nie łapie, oczekiwałeś że ORM będzie Ci sam z siebie walił jakieś JOINy do innych tabel?

No tak na moje oko to nie łapiesz dwóch rzeczy: SQL (bo żadne joiny nie są potrzebne, wystarczy select z where) i tego, do czego służy ORM.
Tak, oczekuję, że ORM będzie ładował obiekty wtedy, gdy są potrzebne do wykonania danej operacji. Jeśli nie potrzebujemy takiego zachowania, to prawdopodobnie nie potrzebujemy też ORMa.

Fajnie że ten 🌼 wyszedł, bo to tylko kolejny argument ku temu, aby częściej w dyskusjach pokazywać kod, bo kod najlepiej weryfikuje rzeczywistość :)

Jaki znowu kwiatek?! Lazy loading to podstawowy mechanizm i idea stojąca za ORM.

nobody01 napisał(a):

Mógłbyś podać przykład?

Customer ma Address, Address ma Country, a kolekcja Country sobie siedzi skeszowana w słowniku w pamięci.

Użycie builder.OwnsMany w klasie konfiguracyjnej to naginanie się do ograniczeń ORMa?

Tak, skoro ORM nie działa jak ORM, to jest mocno ograniczony.
Zobacz sobie jaki SQL wypluwa EF Core po użyciu OwnsMany, a potem pokaż @WeiXiao, żeby zobaczył jak wyglądają joiny robione pod spodem, żeby następnym razem nie wpadał na dziwne insynuacje pod adresem NH.

Shadow properties byly już w 2017: https://stackoverflow.com/a/47650462/13172711
W sumie to chyba od wersji 1.1 z 2016? https://csharp.christiannagel.com/2016/11/07/efcorefields/

Myślę, że już w 2016 to najbardziej udany dowcip w tym wątku. ;)

kalimata napisał(a):

Nie róbmy proszę wojny pomiedzy EF i NH bo nie o tym był temat :)

Nie wiem czy to do mnie uwaga, ale ja z EF tylko lekko kpię, NH to kto inny tu przywołał.

Może mi ktoś dać odpowiedz czy pobieranie danych z bazy moze opierać się na serwisie któy ma metody typu:

public async Task<User> GetByName(string name)
{
return await context.Users.FirstOrDefaultAsync(u=>u.Name==name);
}

czy jednak tak jest zle i powinno się robić inaczej (jak?)

@kalimata: A co Ci da to, że zmienisz nazwę takiej klasy z DAO czy tam repozytorium na serwis? Absolutnie nic, a nawet mniej niż nic, bo serwis to to nie będzie.

Zastanów się nad dwiema rzeczami:

  1. Czy w ogóle potrzebujesz takiej klasy. Każdy wrapper ma jedną zasadniczą wadę - ogranicza możliwości tego, co opakowuje. Czasami to jest potrzebne, ale użyte w złym miejscu powoduje tylko problemy. Alternatywa jest prosta - w kodzie, który implementuje Twój przypadek użycia, używaj ORMa bezpośrednio. Bez dodatkowej warstwy, za to z pełnią możliwości.
  2. A jeśli uważasz, że potrzebujesz takiego wrappera, to niech on coś wnosi. Robienie wrappera na ORMa z metodą, która przyjmuje jakieś Func<cośtam> to jest absurd, przecież to już potrafi ORM. Wrapper niech dostarcza jakiejś abstrakcji i pozwoli jego użytkownikowi nie wiedzieć jak coś ma być zrobione, tylko co ma być zrobione. Dlatego zdecydowanie więcej sensu ma tworzenie metod, tak jak to zaproponowałeś: GetByCośtam.

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