wyszukiwarka według parametrów - budowanie zapytania

0

cześć,
staram się klepać swój projekt i trafiłem teraz na takie zadanie:

załóżmy, że tworzę wyszukiwarkę samochodów (na podstawie jakiegoś tam DTO).
W dto mam około 20 właściwości o które można odpytać (np. kolor, wiek auta, ilość drzwi, ilość KM, itd)
Z góry sorry, za nieporządnie napisany kod, są to w zasadzie pytania teoretyczne, a kod ma mniej więcej nakreślić co robię.

Właściwości te są w 3 klasach - korzystam z Query<> od 3 różnych klas.

Jak to naładniej zbudować ;)?

Póki co idę na łatwiznę,
odpytuje pierwsze Query<params1>:


var query = dao.Query<params1>();

if(dto.kolor.HasValue)
 query = query.Where(x=>x.kolor == dto.kolor)

if(dto.wiek.HasValue)
 query = query.Where(x=>x.wiek== dto.wiek)

i tak sobie kulam zapytanie.
Na koniec sprawdzam czy któreś z tych właściwości w dto zostało okreslone

int identities[] = null;
if(dto.costam.hasValue || dto.costamInnego.HasValue..)
identities = query.select(x=>x.id)

i pytam następną klasę:

QuerySecondClass(identities[]);

a w niej sprawdzam, czy nie dostałem przypadkiem nulla w identities - jeśli tak, to w ogóle nie buduję zapytania na jego podstawie

void QuerySecondClass(int[] identities)
{
Query<params2> query = dao.Query<params2>;

if(identities!= null)
query = query.Where(x=> identities.Contains(samochod.Id));
...

if(dto.innyWarunek)
query=query.where(...)
}

i na końcu znów zbieram identyfikatory, a jesli nic w pytaniu się nie zmienilo, przekazuje nulla do 3 metody, która znow odpytuje przez (inne) Query, przez inne DAO, itd.

wiadomo, że lepszym rozwiązaniem było by budowanie zapytania JOINami, to na pewno zrobię.
Ale czy ktoś jeszcze ma jakieś pomysły ?
Czy da się jakoś nie walić ciągle IFami ;)?

0

Pomysł łamany na pytanie do bardziej doświadczonych, czy coś takiego ma sens:

foreach(var property in typeof(dto).GetProperties())
    if(property.GetValue(dto).HasValue)
        query = query.Where(x => typeof(x).GetProperty(property.Name).GetValue(x) == property.GetValue(dto));

Disclaimer, nie sprawdzałem czy działa i pewnie nie działa... ale może da się jakoś podrasować, by działało, o ile sam pomysł jest dobry?

2

Tak jak @mad_penguin napisał - trzeba dynamicznie zbudować wszystkie Expression. To wygląda rozsądnie: https://nejcskofic.github.io/2017/03/20/dynamic-query-expressions-with-entity-framework/
Zdaje się, że jeszcze parę lat temu była do tego libka, ale coś nie mogę teraz znaleźć.

Ewentualnie można użyć ORMa, który ma takie rzeczy wbudowane.

0

dzięki, o takie cuda mi chodziło. kiedyś to widziałem gdzieś nawet :)

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