Aplikacja w C# do obsługi bazy danych

0

Witam, piszę aplikację w C# która obsłuży moją bazę danych sql - dziennik szkolny. Póki co jakoś brnąłem do przodu ale z 1 rzeczą nie mogę sobie poradzić. Otóż, mam między innymi te 2 tabele:
Przedmioty
-przemiodID (PK)
-przedmiot(varchar)

Ocena
-ocena (float)
-przedmiotID (int)
-uczenID
-data,waga... nieistotne

No i mam przycisk, który wyświetla mi w listboxach oceny ucznia o zadanym ID

 private void button1_Click(object sender, EventArgs e)
        {
            int przedmiot = 1;
            cmd.Connection = cn;           
            listBox1.Items.Clear();
            listBox2.Items.Clear();
            listBox3.Items.Clear();
            listBox4.Items.Clear();
            cn.Open();
            cmd.CommandText = "select Ocena, Data, Waga from ocenaTable where (UczenID = '" + uczenID.Text + "')";
            dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    listBox1.Items.Add(dr[0].ToString());
                    listBox3.Items.Add(dr[1].ToString());
                    listBox4.Items.Add(dr[2].ToString());
                }
            }
            cn.Close();

            cn.Open();

            cmd.CommandText = "select Przedmiot from przedmiotyTable where (PrzedmiotID = '" + przedmiot +"')";
            dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    listBox2.Items.Add(dr[0].ToString());
                }
            }

            cn.Close();
           
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox l = sender as ListBox;
            if (l.SelectedIndex != -1)
            {
                listBox1.SelectedIndex = l.SelectedIndex;
                listBox2.SelectedIndex = l.SelectedIndex;
                listBox3.SelectedIndex = l.SelectedIndex;
                listBox4.SelectedIndex = l.SelectedIndex;
            }
        }

W czym problem? Więc tak, wpisuje ID ucznia, klikam przycisk, dostaje jego: Ocene, IDprzedmiotu, date wystawiena, wage oceny. To dziala. Chce jednak, zeby zamiast ID przedmiotu pojawiła się tam nazwa przedmiotu (matematyka, wf, itp), która kryje się pod ów ID. Wpisałem do kolejnego zaproszenia po prostu zmienną int przedmiot = 1 gdyż nie wiem jak z tego dalej wybrnąć...

wydaje się, że wystarczy tutaj

cmd.CommandText = "select Przedmiot from przedmiotyTable where (PrzedmiotID = '" + przedmiot +"')"; 

jakoś w miejsce + przedmiot + dać wynik z poprzedniego zapytania, w którym dodaje: select przedmiot id... from ocenyTable.

Tylko jak to zrobic?

2

chcesz wyświetlić dane z tabeli "Ocena" z tym, że chcesz aby zamiast pola przedmiotID wyświetlała się nazwa tego przedmiotu?
w takim razie musisz użyć złączenia.

select o.Ocena, o.Data, o.Waga, p.przedmiot from ocenaTable o inner join przedmiotyTable p on (o.przedmiotID = p.przedmiotID) where (UczenID = '" + uczenID.Text + "')"

http://www.sqlpedia.pl/laczenie-tabel-sql/
http://i.stack.imgur.com/VQ5XP.png

0

Dokładnie o to chodziło, dzięki!

0

Napotkałem nowy problem, żeby nie zaśmiecać postanowiłem po prostu odświeżyć stary temat.

Tak więc, powyższy sposób działał, jednak prowadzący miał jeszcze jedno zastrzeżenie co do sprawdzania ocen. Powinno się to odbywać w taki sposób, że użytkownik wpisuje/wybiera z listy ucznia po jego imieniu i nazwisku i w polach ocena, data, przedmiot... pojawiają się wyniki. Tak żeby nie używać IDucznia przez użytkownika programu.

Próbowałem zrobić 2 pola na imie i nazwisko, przycisk który wyzwala:

private void button2_Click(object sender, EventArgs e)
{
cmd.Connection = cn;
cn.Open();

        cmd.CommandText = "Select Iducznia FROM Uczniowie WHERE (Imie ='" + imieBox.Text + "' AND Nazwisko = '" + nazwiskoBox.Text + "')";
        dr = cmd.ExecuteReader();
        if (dr.HasRows)
        {
            while (dr.Read())
            {
                idBox.Text = dr[0].ToString();
            }
        
        }

        cn.Close();

Kolejny przycisk pobiera ID z idBoxu i wyswietla oceny...

Niby jest ok, z tym że chciałbym zrobić coś takiego:
użytkownik wybiera z listy rozwijanej (?) imie i nazwisko ucznia
system wyswietla oceny na podstawie id pobranego z imienia i nazwiska wybranego przez ucznia

jednak nie bardzo wiem jak to obejść? tak by nie wyswietlać ID, nie wpisywać nic?

0

Dodaj comboboxa do formy, i w prawym górnym rogu comboboxa pojawi się przycisk trójkącik, dodaj tam binding. Powinieneś tam wyklikać wszystko co chcesz. Dodajesz później event SelectionChanged, i powinieneś móc pobrać id wyświetlonego nazwiska i zrobić selecta.

0

Nie bardzo wiem jak to zrobić ;( znalazłem jakiś kod w internecie, wyświetla mi on dane w comboxie ale chciałbym teraz żeby na podstawie wybranej danej wyświetlił mi inne (przykład na wyświetalniu uczniów danej klasy)

Ta część odpowiada za wypełnienie comboboxa

 
private void WpiszOceny_Load(object sender, EventArgs e)
        {
                cn.Open();
                SqlCommand sc = new SqlCommand("SELECT IDklasy, Klasa FROM klasyTbl", cn);
                SqlDataReader reader;

                reader = sc.ExecuteReader();
                DataTable dt = new DataTable();
                dt.Columns.Add("ID", typeof(string));
                dt.Columns.Add("Klasa", typeof(string));
                dt.Load(reader);

                comboBox1.ValueMember = "ID";
                comboBox1.DisplayMember = "Klasa";
                comboBox1.DataSource = dt;

                cn.Close();
           }

 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
           IDk = comboBox1.SelectedValue.ToString();
        } 

a ten przycisk powinien po wybraniu danej klasy (1a, 3c, itd) wziąć jej ID (1,2,3) i wyświetlić uczniow tej klasy...

  private void button2_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            listBox2.Items.Clear();
            listBox3.Items.Clear();

            cn.Open();
            cmd.CommandText = "SELECT IDucznia, Imie, Nazwisko FROM uczniowieTbl WHERE (Klasa = '" + IDk + "')";
             // w miejsce IDk próbowałem też comboBox1.SelectedIndex.ToString()
            dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    listBox1.Items.Add(dr[0].ToString());
                    listBox2.Items.Add(dr[1].ToString());
                    listBox3.Items.Add(dr[2].ToString());
                }
            }
            cn.Close();
        }
0

No i co się dzieje jak tak robisz?

0

Hmm... wcześniej wyskakiwały jakieś dziwne błędy, teraz nie dzieje się nic (nie zrobiłem nic)... po prostu nie wyświetla się nic w listboxach, gdy w innym okienku wpiszę klasę recznie i spróbuje wyswietlić to nadal to działa.

0

Z debuggera umiesz korzystać? Jak nie to się naucz i sprawdź jakie zapytanie idzie do bazy pod cmd.CommandText i co jest w dr.
Debugowanie

0

Wszystko już działa jak powinno, poza jednym.. ;D
W taki sposób sie łącze z bazą

SqlConnection cn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Maciej\Desktop\DZIENNIK_BAZA\v1\Dziennik\Dziennik\dbdziennik.mdf;Integrated Security=True;User Instance=True");
        SqlCommand cmd = new SqlCommand(); 

Da się to jakoś obejść (string w miejsce C:... nie bardzo działa), tak by po uruchomieniu programu można ustawić ścieżke ręcznie? Chodzi o to że ta baza na innym komputerze nie będzie działać bez edycji kodu ;(

0

Brzydki troche sposob z trzymaniem connectionow w kodzie, ale skoro koniecznie chcesz to pewnie, ze mozna to zrobic, w koncu to zwykly string;)

string location = WczytajLocationNpZFileBrowseraCzySkadstam();
SqlConnection cn = new SqlConnection(String.Format("Data Source=.\SQLEXPRESS;AttachDbFilename={0};Integrated Security=True;User Instance=True", location);
        SqlCommand cmd = new SqlCommand();

edit: pisane z palca, nie testowane;) Tylko musisz sie upewnic, ze ten string jest dobrze sformatowany, spearatory folderow sa takie jakie powinny itd

0
string location = Environment.GetCurrentDirectory() + "\dbdziennik.mdf" 

Jeśli plik mdf jest w folderze z exekiem to powyższe powinno zadziałać. (też nie testowane)

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