none
DataTable in List<> RRS feed

  • Frage

  • Hallo,

    ich habe schon mehrere Beiträge gelesen aber verstehe nicht wie ich ein DataTable in eine List<> bekomme.

    ich habe ien SQL Connection mit einem command und in dem DataTable sind auch 3 einträge drinnen aber wie bekomme ich nun diese 3 Einträge in eine List<>???

    überall lese ich was von einer ForeachSchleife

    foreach (DataTable table in dataSet.Tables) foreach (DataRow row in table.Rows) foreach (DataColumn column in table.Columns) if (row[column] != null) Console.WriteLine(row[column]);

    Allerdings wenn ich es versuche dann sagt er mir das der Name .Columns nicht exestiert.

    Bin ich nun zu doff oder könnte es mir bitte jemand für Dummies erklärern bitte.

    Und vor allem wie bekomme ich es in die List<> ??

    Danke

    Cay

    Dienstag, 18. März 2014 19:51

Antworten

  • Hallo Cay,

    3 Einträge sagt einem dennoch erstmal gar nix. ID ist von welchem Datentyp? Welche Liste soll es werden (Datentyp)? ...

    List<Int32> meineListe = new List<Int32>();
    
    foreach( DataRow row in table.Rows ) {
        meineListe.Add( row["ID"] );
    }
    
    So könnte es dann gehen, wenn ID ein Integerwert ist.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert joksch_c Mittwoch, 19. März 2014 06:48
    Dienstag, 18. März 2014 20:06
    Moderator
  • Hallo,
    der Ansatz mit der Foreach-Schleife ist schon richtig. Du darfst dabei aber nur die Rows-Auflistung durch gehen und dabei alle Elemente übertragen.

    Für mein folgendes Beispiel wälte ich diesen Versuchsaufbau:

    DataTable table = new DataTable();
    table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));//2 Beispielspalten
    
    for (int i = 0; i < 15; ++i)
        table.Rows.Add(i, "Name " + i);//15 Beispieldatensätze hinzufügen
    Nun musst du zunächst eine List<T> deklarieren:
    List<dynamic> list = new List<dynamic>();
    Ich werde also mehrere dynamische Objekte hinzufügen. Du kannst auch eine ganz normale Klasse angeben, die die Infos eines Datensatzes speichern kann.
    foreach (DataRow row in table.Rows)//Alle Zeilen durch gehen
    {
        list.Add(new //Bei einer Klasse hier den Klassennamen hinter new angeben
        {
            Id = int.Parse(row["ID"].ToString()),//Einfach die Eigenschaften deiner Klasse/des dynamischen Typs zuweisen
            Name = row["Name"]//Die dynamischen Eigenschaften musst du nicht extra deklarieren. Der Compiler erkennt diese automatisch
        });
    }
    
    //Mache was mit deiner List<T>
    //Beispielsweise alle ausgeben:
    foreach (dynamic item in list)
    {
        Console.WriteLine(item.Id);
        Console.WriteLine(item.Name);//Die Eigenschaften werden automatisch zur Laufzeit aufgelöst - eine Eigenheit von dynamic
    }
    PS: Ich habe in meinem Beispiel 2 Spalten: ID und Name. Du müsstest dort die Spalten angeben, die du per SQL abfragst.



    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.


    Dienstag, 18. März 2014 20:03
    Moderator
  • Hallo,
    eine mit dynamic erstellte Variable entspricht einer richtigen Klasseninstanz. Eine normale Klasse kann man nicht einfach nach dem kompilieren um weitere Eigenschaften erweitern, eine mit dynamic erzeugte Variable also auch nicht. Es geht also nicht.

    Wenn du nicht weißt, welche Spalten es gibt, dann musst du auf eine Liste (/Array/Dictionary/...) zurück greifen. Nur damit ist es möglich, eine unbestimmte Anzahl von Informationen zu speichern.

    dynamic ist wirklich nur praktisch, wenn man weiß wie die Daten aussehen, die man abspeichern möchte.

    Das DataTable hat eine Columns-Eigenschaft über die du auch an die Spaltennamen heran kommst. Dann kannst du in etwa so eine Liste von Werten speichern:

    DataTable table = new DataTable();
    
    var rows = new List<Dictionary<string, object>>();
    foreach (DataRow row in table.Rows)
    {
        var cols = new Dictionary<string, object>();//Schlüssel = Spaltenname, Value = Wert
        foreach (DataGridViewColumn col in table.Columns)
        {
            cols.Add(col.Name, row[col.Name]);//Wert in das Dictionary aufnehmen
        }
        rows.Add(cols);//Zeile in der Liste sichern
    }
    
    //rows enthält nun alle Daten des DataTable
    //Die List<T> enthält die Zeilen und das Dictionary<T,T>
    //enthält die einzelnen Werte in der Zeile, geordnet nach Spaltenname
    Der Code ist ungetestet, sollte aber so in etwa funktionieren.

    Und bitte nicht böse sein wenn das nicht möglich ist und es jeder wissen sollte.

    dynamic ist zwar eine Grundlage in C#, aber keine die man zwingend oder ständig braucht. Böse ist dir deswegen keiner. Jeder fängt mal klein an ;)


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert joksch_c Samstag, 22. März 2014 09:41
    Freitag, 21. März 2014 14:23
    Moderator

Alle Antworten

  • Hallo Cay,

    wenn Du die Spaltennamen kennst, kannst Du die auch mit Namen ansprechen. Ansonsten über den Index. Die Schleife über die Spalten bringt dir nur bedingt was, da Du die Werte ja wahrscheinlich einer Eigenschaft innerhalb des Listenelements zuweisen willst, oder?

    List<DeineKlasse> meineListe = new List<MeineKlasse>();
    
    foreach( DataRow row in table.Rows ) {
        meineListe.Add( new DeineKlasse( row["Spaltenname"] ) );
    }
    

    Das wäre eine Möglichkeit. Solange Du uns aber nicht verrätst, welche Art von Liste Du da erstellen willst, wie dein SQL Statement bzw. die DataTable genau aussieht, kann man da nicht viel helfen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 18. März 2014 20:00
    Moderator
  • Hallo,
    der Ansatz mit der Foreach-Schleife ist schon richtig. Du darfst dabei aber nur die Rows-Auflistung durch gehen und dabei alle Elemente übertragen.

    Für mein folgendes Beispiel wälte ich diesen Versuchsaufbau:

    DataTable table = new DataTable();
    table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));//2 Beispielspalten
    
    for (int i = 0; i < 15; ++i)
        table.Rows.Add(i, "Name " + i);//15 Beispieldatensätze hinzufügen
    Nun musst du zunächst eine List<T> deklarieren:
    List<dynamic> list = new List<dynamic>();
    Ich werde also mehrere dynamische Objekte hinzufügen. Du kannst auch eine ganz normale Klasse angeben, die die Infos eines Datensatzes speichern kann.
    foreach (DataRow row in table.Rows)//Alle Zeilen durch gehen
    {
        list.Add(new //Bei einer Klasse hier den Klassennamen hinter new angeben
        {
            Id = int.Parse(row["ID"].ToString()),//Einfach die Eigenschaften deiner Klasse/des dynamischen Typs zuweisen
            Name = row["Name"]//Die dynamischen Eigenschaften musst du nicht extra deklarieren. Der Compiler erkennt diese automatisch
        });
    }
    
    //Mache was mit deiner List<T>
    //Beispielsweise alle ausgeben:
    foreach (dynamic item in list)
    {
        Console.WriteLine(item.Id);
        Console.WriteLine(item.Name);//Die Eigenschaften werden automatisch zur Laufzeit aufgelöst - eine Eigenheit von dynamic
    }
    PS: Ich habe in meinem Beispiel 2 Spalten: ID und Name. Du müsstest dort die Spalten angeben, die du per SQL abfragst.



    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.


    Dienstag, 18. März 2014 20:03
    Moderator
  • Hallo,

    es ist eine abfrage aus einer SQL Datenbank die Tabelle dorten hat 5 spalten und mehrere Einträge die durch diese SQL Abfrage gefiltert wird.

    SELECT ID FROM dbContractArt WHERE ID NOT IN (SELECT FKContract FROM MemberContract WHERE FKMember = " + selmember + ")"

    Somit habe ich dann 3 Einträge und die möchte ich in eine einfache Liste drinnen haben.Hoffe das reicht dir ??

    grüße

    cay

    Dienstag, 18. März 2014 20:03
  • Hallo Cay,

    3 Einträge sagt einem dennoch erstmal gar nix. ID ist von welchem Datentyp? Welche Liste soll es werden (Datentyp)? ...

    List<Int32> meineListe = new List<Int32>();
    
    foreach( DataRow row in table.Rows ) {
        meineListe.Add( row["ID"] );
    }
    
    So könnte es dann gehen, wenn ID ein Integerwert ist.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert joksch_c Mittwoch, 19. März 2014 06:48
    Dienstag, 18. März 2014 20:06
    Moderator
  • Hi,

    also

    ich habe in der Datenbank folgende sachen drinnen:

    int, Date, date, String, bool

    Diese 5 Spalten gibt es in der Datenbank

    grüße

    Cay

    Dienstag, 18. März 2014 20:10
  • Hallo Cay,

    schön für dich :)

    Ich mein das nicht böse aber setzt Du voraus, dass wir auch nur irgendwas über deine Datenbank, deren Tabellen und wiederum deren Inhalte wissen?

    Geh doch mal langsam und überlegt an die Sache ran und schau, welche Informationen Du brauchen würdest, wenn dir jemand eine solche Frage stellen würde und Du wirklich rein gar nichts über das System des Fragestellers wissen würdest.

    Du hast eine Tabelle mit fünf Spalten. Ok.

    Die Spalten sind von den genannten Datentypen. Auch Ok.

    Aber welchen Datentyp ID hat, weiß man so immer noch nicht. Man kann sich zwar jetzt denken, dass die erste Spalte "ID" heißt, dass die wahrscheinlich auch den Datentyp int hat aber denken ist nicht wissen :)

    So oder so, falls meine Annahmen stimmen, sollte der Code in meinem vorigen Posting passen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 18. März 2014 20:15
    Moderator
  • Hallo Stefan,

    ich hatte doch gepostet was es für Datentypen sind :)

    Hi,

    also

    ich habe in der Datenbank folgende sachen drinnen:

    int, Date, date, String, bool

    Diese 5 Spalten gibt es in der Datenbank

    aber deine Lösung passt.

    Habe sie aber gerade erst ausprobiert.

    grüße

    cay

    Mittwoch, 19. März 2014 06:46
  • Hallo,

    nochmal eine kleine Frage zu dieser List<dynamic>.

    ist es möglich diese Liste variable zu füllen ohne das man weiss welche Spalten in der SQL Tabelle vorhanden sind ??

    Das heisst ich übergebe der SQL Abfrage einfach einen queryString.

    Resultat daraus ist ja ein DataTable mit x Columns und x Rows mit beliebigen Namen

    Ist es nun möglich mit in diese List<dynamic> irgendwie die daten zu bekommen ???

    grüße

    Cay

    Und bitte nicht böse sein wenn das nicht möglich ist und es jeder wissen sollte.

    Ich weiss es nicht.

    Freitag, 21. März 2014 14:07
  • Hallo,
    eine mit dynamic erstellte Variable entspricht einer richtigen Klasseninstanz. Eine normale Klasse kann man nicht einfach nach dem kompilieren um weitere Eigenschaften erweitern, eine mit dynamic erzeugte Variable also auch nicht. Es geht also nicht.

    Wenn du nicht weißt, welche Spalten es gibt, dann musst du auf eine Liste (/Array/Dictionary/...) zurück greifen. Nur damit ist es möglich, eine unbestimmte Anzahl von Informationen zu speichern.

    dynamic ist wirklich nur praktisch, wenn man weiß wie die Daten aussehen, die man abspeichern möchte.

    Das DataTable hat eine Columns-Eigenschaft über die du auch an die Spaltennamen heran kommst. Dann kannst du in etwa so eine Liste von Werten speichern:

    DataTable table = new DataTable();
    
    var rows = new List<Dictionary<string, object>>();
    foreach (DataRow row in table.Rows)
    {
        var cols = new Dictionary<string, object>();//Schlüssel = Spaltenname, Value = Wert
        foreach (DataGridViewColumn col in table.Columns)
        {
            cols.Add(col.Name, row[col.Name]);//Wert in das Dictionary aufnehmen
        }
        rows.Add(cols);//Zeile in der Liste sichern
    }
    
    //rows enthält nun alle Daten des DataTable
    //Die List<T> enthält die Zeilen und das Dictionary<T,T>
    //enthält die einzelnen Werte in der Zeile, geordnet nach Spaltenname
    Der Code ist ungetestet, sollte aber so in etwa funktionieren.

    Und bitte nicht böse sein wenn das nicht möglich ist und es jeder wissen sollte.

    dynamic ist zwar eine Grundlage in C#, aber keine die man zwingend oder ständig braucht. Böse ist dir deswegen keiner. Jeder fängt mal klein an ;)


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert joksch_c Samstag, 22. März 2014 09:41
    Freitag, 21. März 2014 14:23
    Moderator
  • Danke für die Hilfe.

    Funktioniert alles

    grüße


    Cay

    Samstag, 22. März 2014 09:41