Autor Beitrag
ottto
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Fr 13.09.19 11:17 
Hallo zusammen,
ich hab eine Frage zum objektorientiertem Aufbau meines Programms.
Meine DataTable wird mit Daten aus einer XML-Datei gefüllt.
Dabei sehe ich jetzt zwei Möglichkeiten die Elemente der XML-Datei in meine DataTable zu schreiben.
Die erste geht, meiner Meinung nach, an der Objektorientierung vorbei, indem ich die ausgelesenen Daten direkt dt.Rows.Add(e1, e2, d1, d2, bs, lio) in die dt schreibe.
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
        private void ButXMLEinlesen_Click(object sender, EventArgs e)
        {
            if (!File.Exists(qDatei))
            {
                MessageBox.Show("Datei " + qDatei + " gibt es nicht!!!");
                return;
            }
            string e1 = "!!!";
            string e2 = "!!!";
            string d1 = "!!!";
            string d2 = "!!!";
            string bs = "!!!";
            DateTime lio = new DateTime();

            XmlReader xr = XmlReader.Create(qDatei);
            while (xr.Read())
            {
                if (xr.NodeType == XmlNodeType.Element)
                {
                    switch (xr.Name)
                    {
                        case "eng1":
                            e1 = xr.ReadString();
                            break;
                        case "eng2":
                            e2 = xr.ReadString();
                            break;
                        case "deu1":
                            d1 = xr.ReadString();
                            break;
                        case "deu2":
                            d2 = xr.ReadString();
                            break;
                        case "beispielsatz":
                            bs = xr.ReadString();
                            break;
                        case "letzterIO":
                            lio = Convert.ToDateTime(xr.ReadString());

                            dt.Rows.Add(e1, e2, d1, d2, bs, lio);
                            //Vokabeln.Add(new Vokabel(e1, e2, d1, d2, bs, lio));
                            break;
                    }
                }
            }
            xr.Close();
        }


Bei der zweiten lese ich Objekte aus der XML-Datei und schreibe diese Vokabeln.Add(new Vokabel(e1, e2, d1, d2, bs, lio)) in eine Liste. Danach lese ich diese Liste mit foreach und schreibe die Daten dann erst in meine DT.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
        List<Vokabel> Vokabeln = new List<Vokabel>();

        private void ButXMLEinlesen_Click(object sender, EventArgs e)
        {
            if (!File.Exists(qDatei))
            {
                MessageBox.Show("Datei " + qDatei + " gibt es nicht!!!");
                return;
            }
            string e1 = "!!!";
            string e2 = "!!!";
            string d1 = "!!!";
            string d2 = "!!!";
            string bs = "!!!";
            DateTime lio = new DateTime();

            XmlReader xr = XmlReader.Create(qDatei);
            while (xr.Read())
            {
                if (xr.NodeType == XmlNodeType.Element)
                {
                    switch (xr.Name)
                    {
                        case "eng1":
                            e1 = xr.ReadString();
                            break;
                        case "eng2":
                            e2 = xr.ReadString();
                            break;
                        case "deu1":
                            d1 = xr.ReadString();
                            break;
                        case "deu2":
                            d2 = xr.ReadString();
                            break;
                        case "beispielsatz":
                            bs = xr.ReadString();
                            break;
                        case "letzterIO":
                            lio = Convert.ToDateTime(xr.ReadString());

                            //dt.Rows.Add(e1, e2, d1, d2, bs, lio);
                            Vokabeln.Add(new Vokabel(e1, e2, d1, d2, bs, lio));
                            break;
                    }
                }
            }
            xr.Close();

            foreach (Vokabel v in Vokabeln)
            {
                dt.Rows.Add(v.eng1, v.eng2, v.deu1, v.deu2, v.beispielsatz, v.letzerIO);
            }

        }


Welche Lösung sollte ich verwenden oder gibt es eine bessere? Gibt es bei der zweiten eine Möglichkeit die Liste einzusparen?

Hier noch die Definition der DataTable und der Vokabel:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
        public DataTable dt = new DataTable("Vokabelliste");

        private void FormStart_Load(object sender, EventArgs e)
        {
            dt.Columns.Add("Eng1", System.Type.GetType("System.String"));
            dt.Columns["Eng1"].AllowDBNull = false//Spalte muss gefüllt sein.
            //dt.Columns["Eng1"].Unique = true; //Inhalt darf nicht doppelt sein
            dt.Columns.Add("Eng2", System.Type.GetType("System.String"));
            dt.Columns.Add("Deu1", System.Type.GetType("System.String"));
            dt.Columns["Deu1"].AllowDBNull = false;
            dt.Columns.Add("Deu2", System.Type.GetType("System.String"));
            dt.Columns.Add("Beispielsatz", System.Type.GetType("System.String"));
            dt.Columns.Add("iO gelöst", System.Type.GetType("System.DateTime"));
            dt.Columns["iO gelöst"].ReadOnly = true;
            //dt.Rows.Add("read", "", "lesen", "" , "BeispielSatz!!!", new DateTime(1999, 02, 02));
        }

    class Vokabel
    {
        public readonly string eng1;
        public readonly string eng2;
        public readonly string deu1;
        public readonly string deu2;
        public readonly string beispielsatz;
        public readonly DateTime letzerIO;

        public Vokabel(string e1, string e2, string d1, string d2, string bs, DateTime lio)
        {
            eng1 = e1;
            eng2 = e2;
            deu1 = d1;
            deu2 = d2;
            beispielsatz = bs;
            letzerIO = lio;
        }    
    }



Danke.
Gruß.
ottto

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4157
Erhaltene Danke: 865

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Sa 14.09.19 10:06 
Egal ob du die Daten zuerst in eine Liste einliest oder aber direkt in eine DataTable, du solltest aber die Methode aus der Form-Klasse auslagern (=> Datenzugriffsschicht).

Deine zweite Methode ohne die Liste entspricht doch dann deiner ersten Methode?!

Die generelle Frage lautet eher: Ist die DataTable wirklich die beste Struktur oder wäre nicht doch List<Vokabel> besser geeignet, um damit im Programm weiterzuarbeiten?

PS: Statt der public readonly-Variablen (in class Vokabel) benutzt man eigentlich besser (Nur-Lese) Eigenschaften dafür:
ausblenden C#-Quelltext
1:
public string Eng1 { get; } // und der C#-Namenskonvention entsprechend mit großem Anfangsbuchstaben					

Für diesen Beitrag haben gedankt: ottto
ottto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Mo 16.09.19 16:27 
Vielen Dank für die Tipps. Welche Klasse macht den meisten Sinn, zum Auslagern der Methode?
Gehört sowas in die class Vokabeln oder eher in die class Program?
Danke.
Gruß.
ottto
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4449
Erhaltene Danke: 917


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 16.09.19 16:44 
Zitat:
Gehört sowas in die class Vokabeln oder eher in die class Program?

Weder noch. Es gehört in eine 3.te Klasse in der du den Code zum Einlesen der xml (und alles was vielleicht später noch dazu kommt) verlagerst und dir eine List<Vokabel> rausrückt.

Moderiert von user profile iconTh69: C#- durch Quote-Tags ersetzt

Für diesen Beitrag haben gedankt: ottto
ottto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Mo 16.09.19 16:55 
Die geänderte Liste würde dann auch wieder in eine Datei gespeichert werden.
Gehört dies dann mit in diese Klasse oder sollte das dann wieder in eine eigene?
Danke.
Gruß.
ottto
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4157
Erhaltene Danke: 865

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Mo 16.09.19 20:26 
Das kommt wohl auf den Umfang der Methoden an. Bei nur zwei Hauptmethoden würde eine Klasse mit den beiden Methoden Load und Save ausreichen (alternativ zwei Klassen, z.B. VocableReader und VocableWriter).

Hier noch zwei Links zur sogenannten 3-Schichten-Architektur (da dir das anscheinend noch unbekannt ist):
HowTo: 3-Tier / 3-Schichten Architektur
Wie funktioniert die 3-Schichten-Architektur?