Dapper - pomoc w zapytaniu z multi mappowaniem

0

Witam.
Potrzebuje nakierowania czy jest opcja, aby ogarnąć to Dapperem.

public class Podatnik
{
   //... Jakieś tam properties
   public List<UrzadzeniePodatnika> UrzadzeniaPodatnika {get;set;}
}

public class UrzadzeniePodatnika
{
   //... Jakieś tam properties
   public List<Zdarzenie> Zdarzenia {get;set;}
}

public class Zdarzenie
{
   //... Jakieś tam properties
}

Chce wyciągnąć wszystkie dane, czyli wszystkie urządzenia danego podatnika i wszystkie zdarzenia tychże urządzeń

select * from dbo.Podatnicy left join dbo.UrzadzeniaPodatnika on PdT_PdTId = UdP_PdTId left join dbo.Zdarzenia on UdP_UdPId = ZdR_UdPId

Mam zrobione coś takiego, ale chciałbym, aby mi zwróciło listę podatników i wszystkie ich dane, a nie jednego podatnika, urządzenie i zdarzenie...

            using (IDbConnection db = new SqlConnection(connectionString))
            {
                var list = db.Query<Podatnik, UrzadzeniePodatnika, Zdarzenie, Podatnik>(
                    query, (p, up, zdr) =>
                    {
                        var aqq1 = up;
                        var aqq2 = p;
                        var aqq3 = zdr;

                        return p;
                    }, splitOn: "PdT_PdTId,UdP_PdTId,UdP_UdPId,ZdR_UdPId");


                var aqq = list;
            }

Ktoś jest w stanie mnie nakierować jak to ogarnąć?

0

Dapper został stworzony do innego podejścia, to proste narzędzie do mapowania danych relacyjnych na obiekty, tymczasem Ty potrzebujesz całkiem skomplikowanej transformacji wyniku zapytania. Pewnie istnieje do tego jakaś biblioteczka, ale można to też na szybko napisać w taki sposób:

var podatnicyTemp = new Dictionary<int, Podatnik>();
var urzadzeniaTemp = new Dictionary<int, UrzadzeniePodatnika>();
var data = connection.Query<Podatnik, UrzadzeniePodatnika, Zdarzenie, Podatnik>(sql,
    (p, u, z) =>
    {
        if (!urzadzeniaTemp.ContainsKey(u.Id))
        {
            urzadzeniaTemp.Add(u.Id, u);
        }
        urzadzeniaTemp[u.Id].Zdarzenia.Add(z);

        if (!podatnicyTemp.ContainsKey(p.Id))
        {
            podatnicyTemp.Add(p.Id, p);
        }
        if (!podatnicyTemp[p.Id].UrzadzeniaPodatnika.Any(x => x.Id == u.Id))
        {
            podatnicyTemp[p.Id].UrzadzeniaPodatnika.Add(u);
        }

        return podatnicyTemp[p.Id];
    })
    .Distinct();

Tylko czy tak naprawdę tego potrzebujesz? Zgaduję, że w ten sposób odtwarzasz w pamięci strukturę bazy danych. Nie jest to raczej potrzebne ani do wyświetlania, ani do przetwarzania danych. Na Twoim miejscu przemyślałbym wymagania i sposób rozwiązania.

0

Po stronie klienta robię szukajkę, która powinna być jak najbardziej dynamiczna i addytywna. Do tego potrzebuje pełnego zestawu danych. Może i masz racje, może i faktycznie nie jest to dobre podejście. Tylko jak zrobić dynamiczne filtry w Dapper? Jeśli ktoś w polu szukaj wpisze numer telefonu, to skąd mam wiedzieć, że teraz szuka po numerze telefonu, a nie po numerze nip.

PS.
Wcześniej miałem jeszcze debilniej zrobione. Puszczałem szukaną frazę przez każde property obiektu i ich wartości i jeśli zwracał true to dodawałem obiekt do listy...

0

Przede wszystkim, to robienie tego po stronie klienta niekoniecznie jest optymalne.

Ale mniejsza z tym - jak wyświetlasz wyniki tego wyszukiwania? W jakimś gridzie, czy hierarchicznie?

0

A jakie masz query?
Sam używam Dappera i ja buduje dynamiczne zapytania w procedurze SQL. Jeśli przekazany parametr ma wartość to dodawany jest warunek do SELECT. Innym sposobem jest pobranie wszystkiego i filtrowanie danych na tabeli/gridzie przy wykorzystaniu js.

0

@rmawerik: Ściągnałem wszystko zapytaniem bez parametrów i filtruje swoim pipe'em po stronie klienta. Jak wspomniał @somekind działa to tragicznie, więc w wolnej chwili muszę zmienić szukanie na enter, bo dynamicznie ścina nawet samo wpisywanie... :D

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