C# + MySQL + rozbudowany select i problem z DataReader

0

Witam, staram się wydobyć z bazy parę rzeczy i natrafiłem na mały problem, którego nie potrafię przeskoczyć, mianowicie wymodziłem coś takiego :

 MySqlCommand cmd = new MySqlCommand("SELECT kth.idkth, kth.nazwa_firmy, kth.nip, kth.regon, kth_adres.ulica, " +
                    "kth_adres.kod_poczt, kth_adres.miasto, kth_adres.nr_domu, kth_grupa.nazwa " +
                    "FROM kth INNER JOIN kth_adres ON kth_adres.id_kth = kth.idkth AND kth.idkth='"+this.kthId.ToString()+"' " +
                    "LEFT JOIN kth_grupa ON kth_grupa.id_kth_grupa = kth.id_grupa_kth "+
                    "INNER JOIN kth_obslugujacy ON kth.id_obslugujacy = kth_obslugujacy.id_obslugujacy",this.formaGlowna.mysqlConnection);

Pobranie danych z tabeli KTH, KTH_ADRES, KTH_GRUPA, KTH_OBSLUGUJACY

Problem polega na tym, że KTH może mieć N adresów i teraz jak to wczytać np. do RichBox
W php zrobiłbym :

 FOR liczba KTH do 
  BEGIN
     POBIERZ DANE KTH
      DODAJ DO ODPOWIEDNICH KONTROLEK
     POBIERZ ID_ADRESU
       FOR LICZBA ADRESOW W KTH_ADRES DO 
         BEGIN
            DODAJ KAZDY ADRES DO RICHBOX
         END   
  END

No ale tutaj nie mogę zastosować dwa razy DataReader'a. A jeżeli zamknę główny DataReader na potrzeby podzapytania o adresy, stracę informacje o pozostałych rekordach :/

0

Patrz, od razu lepiej się ogląda SQL'a(choć ten kth to mógłby być napisany w całości)
Ponadto do filtrowania używa się WHERE

SELECT kth.idkth
	,kth.nazwa_firmy
	,kth.nip
	,kth.regon
	,kth_adres.ulica
	,kth_adres.kod_poczt
	,kth_adres.miasto
	,kth_adres.nr_domu
	,kth_grupa.nazwa
FROM kth 
INNER JOIN kth_adres 
	ON kth_adres.id_kth = kth.idkth
LEFT JOIN kth_grupa 
	ON kth_grupa.id_kth_grupa = kth.id_grupa_kth 
INNER JOIN kth_obslugujacy 
	ON kth.id_obslugujacy = kth_obslugujacy.id_obslugujacy
WHERE kth.idkth = @idkth
 

To powinno zwrócić zbiór wyników.
Nie wiem, jakiego connectora używasz, ale standardowo jest tak:

MySqlDataReader reader = command.ExecuteReader();

            while (reader.Read())
            {
                //pobierasz kolejne wiersze
                int id = (int)reader["kth.idkth"];
            }
            reader.Close(); 

Reader.Read() przechodzi do następnego wiersza i zwraca true jeśli ten wiersz istnieje. licznik zaczyna się od -1, dlatego wołamy reader.Read() przed pierwszym odczytem.

0

a co do N adresów, to znajdują się one w wynikach zapytania, wystarczy dodać na końcu SQL'a

ORDER BY idkth
 

i w kodzie

int id = -1;
while (reader.Read())
            {
                //pobierasz kolejne wiersze
                int _id = (int)reader["kth.idkth"];
                if(id == _id)//ten sam kontrahent, inny adres
                {}
                else//nastepny kontrachent
                { id = _id; }
            }
            reader.Close(); 
 
0

Odnośnie tego WHERE - ok, prawda, zgodzę się, dzięki za zwrócenie uwagi :)

Ale chyba nie jasno opisałem mój problem.
Jest powyżej pseudo kod - jak zrobiłbym to w PHP. Chciałem wczytać wszystkie potrzebne mi dane, można powiedzieć 'od razu'.

Czyli pobieram kontrahenta i teraz patrzę sobie, Aha ! kontrahent posiada 3 adresy (główny/oddział/oddział)
Więc...
Do odpowiednich pól - dodaję informacje o kontrahencie (nazwa/nip etc.)
Do np. richbox'a - dodaję wszystkie jego adresy (w tym wypadku trzy (3) )

identyczna sytuacja wystąpi z kontaktami - może istnieć N osób do kontaktu, do tego telefon do biura/magazyn etc.

I w ten sposób chciałbym wczytać dane z bazy - tak bynajmniej zrobiłbym to w PHP, tutaj, nie mogę użyć dwóch DataReader, bowiem gdy jeden korzysta z połączenia - blokuje je. Musiałbym pewnie nawiązać drugie połączenie do bazy, żeby móc użyć drugiego DataReader i zrealizować to identycznie jak w PHP. Niestety nie mogę mięć dwóch połączeń :)

// napisałeś post podczas gdy ja pisałem swoje wypociny :) I faktycznie to też jest sposób :)

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