Wie extrahiere ich Daten aus einer DataTable?

77

Ich habe eine DataTable, die von einer SQL-Abfrage in eine lokale Datenbank ausgefüllt wird, aber ich weiß nicht, wie ich Daten daraus extrahieren soll. Hauptmethode (im Testprogramm):

static void Main(string[] args)
{
    const string connectionString = "server=localhost\\SQLExpress;database=master;integrated Security=SSPI;";
    DataTable table = new DataTable("allPrograms");

    using (var conn = new SqlConnection(connectionString))
    {
        Console.WriteLine("connection created successfuly");

        string command = "SELECT * FROM Programs";

        using (var cmd = new SqlCommand(command, conn))
        {
            Console.WriteLine("command created successfuly");

            SqlDataAdapter adapt = new SqlDataAdapter(cmd);

            conn.Open(); 
            Console.WriteLine("connection opened successfuly");
            adapt.Fill(table);
            conn.Close();
            Console.WriteLine("connection closed successfuly");
        }
    }

    Console.Read();
}

Der Befehl, mit dem ich die Tabellen in meiner Datenbank erstellt habe:

create table programs
(
    progid int primary key identity(1,1),
    name nvarchar(255),
    description nvarchar(500),
    iconFile nvarchar(255),
    installScript nvarchar(255)
)

Wie kann ich Daten aus dem DataTablein ein sinnvoll zu verwendendes Formular extrahieren ?

RCIX
quelle

Antworten:

155

Die DataTable enthält eine Sammlung .Rowsvon DataRow-Elementen.

Jede DataRow entspricht einer Zeile in Ihrer Datenbank und enthält eine Sammlung von Spalten.

Gehen Sie folgendermaßen vor, um auf einen einzelnen Wert zuzugreifen:

 foreach(DataRow row in YourDataTable.Rows)
 { 
     string name = row["name"].ToString();
     string description = row["description"].ToString();
     string icoFileName = row["iconFile"].ToString();
     string installScript = row["installScript"].ToString();
 }
marc_s
quelle
2
Ich weiß, dass dies eine alte Antwort ist, aber müssen Sie nicht in der foreach-Schleife umwandeln, um die Indizierung zu ermöglichen? Ich konnte so etwas erst tun, als ich den Code wie folgt geändert habe: foreach (DataRow-Zeile in YourDataTable.Rows.Cast <DataRow> ()) ...
awh112
1
Noch älterer Kommentar, aber es besteht keine Notwendigkeit zu besetzen: foreachfunktioniert, weil Rowses sich um eine Sammlung handelt ( DataRowCollection). Sie müssen jedoch verwenden, .Cast<DataRow>()wenn Sie einige Linq-Methoden verwenden möchten ( .Where()zum Beispiel).
Anderson Pimentel
24

Sie können die Datentabelle als Datenquelle für viele Elemente festlegen.

Zum Beispiel

Rasteransicht

Verstärker

Datalist

etc etc.

Wenn Sie Daten aus jeder Zeile extrahieren müssen, können Sie verwenden

table.rows[rowindex][columnindex]

oder

wenn Sie den Spaltennamen kennen

table.rows[rowindex][columnname]

Wenn Sie die Tabelle iterieren müssen, können Sie entweder eine for-Schleife oder eine foreach-Schleife wie verwenden

for ( int i = 0; i < table.rows.length; i ++ )
{
    string name = table.rows[i]["columnname"].ToString();
}

foreach ( DataRow dr in table.Rows )
{
    string name = dr["columnname"].ToString();
}
rahul
quelle
foreach (DataRow dr in Tabelle) table.Rows
StampedeXV
7

Der einfachste Weg, Daten aus einem zu extrahieren, DataTablewenn Sie mehrere Datentypen (nicht nur Zeichenfolgen) haben, ist die Verwendung der Field<T>in der System.Data.DataSetExtensionsAssembly verfügbaren Erweiterungsmethode .

var id = row.Field<int>("ID");         // extract and parse int
var name = row.Field<string>("Name");  // extract string

Von MSDN ist die Field<T>Methode:

Bietet einen stark typisierten Zugriff auf alle Spaltenwerte in der DataRow.

Dies bedeutet, dass bei Angabe des Typs das Objekt überprüft und entpackt wird.

Zum Beispiel:

// iterate over the rows of the datatable
foreach (var row in table.AsEnumerable())  // AsEnumerable() returns IEnumerable<DataRow>
{
    var id = row.Field<int>("ID");                           // int
    var name = row.Field<string>("Name");                    // string
    var orderValue = row.Field<decimal>("OrderValue");       // decimal
    var interestRate = row.Field<double>("InterestRate");    // double
    var isActive = row.Field<bool>("Active");                // bool
    var orderDate = row.Field<DateTime>("OrderDate");        // DateTime
}

Es werden auch nullfähige Typen unterstützt:

DateTime? date = row.Field<DateTime?>("DateColumn");

Dies kann das Extrahieren von Daten vereinfachen, DataTableda das Objekt nicht mehr explizit in die richtigen Typen konvertiert oder analysiert werden muss.

haldo
quelle
4

Bitte erwägen Sie die Verwendung eines solchen Codes:

SqlDataReader reader = command.ExecuteReader();
int numRows = 0;
DataTable dt = new DataTable();

dt.Load(reader);
numRows = dt.Rows.Count;

string attended_type = "";

for (int index = 0; index < numRows; index++)
{
    attended_type = dt.Rows[indice2]["columnname"].ToString();
}

reader.Close();
Salimido
quelle
3

Sofern Sie keinen bestimmten Grund haben, raw ado.net zu verwenden, würde ich einen ORM (Object Relational Mapper) wie nHibernate oder LINQ to SQL verwenden. Auf diese Weise können Sie die Datenbank abfragen und Objekte zum Arbeiten abrufen, die stark typisiert sind und mit IMHO einfacher zu arbeiten sind.

Pythonandchips
quelle
1
Ich erhalte Grundkenntnisse in ADO.net, bevor ich zu einem ORM übergehe,
RCIX
-1
  var table = Tables[0]; //get first table from Dataset
  foreach (DataRow row in table.Rows)
     {
       foreach (var item in row.ItemArray)
         {
            console.Write("Value:"+item);
         }
     }
Hamid Bahmanabady
quelle
Diese Antwort würde von einer Erklärung profitieren. Nur-Code-Antworten sind auf lange Sicht selten nützlich.
TylerH
-1

Bitte beachten Sie, dass das Öffnen und Schließen der Verbindung bei Verwendung von DataAdapter nicht erforderlich ist.

Daher schlage ich vor, diesen Code zu aktualisieren und das Öffnen und Schließen der Verbindung zu entfernen:

        SqlDataAdapter adapt = new SqlDataAdapter(cmd);

conn.Open (); // Diese Codezeile ist nicht erforderlich

        Console.WriteLine("connection opened successfuly");
        adapt.Fill(table);

conn.Close (); // Diese Codezeile ist nicht erforderlich

        Console.WriteLine("connection closed successfuly");

Referenzdokumentation

Der in diesem Beispiel gezeigte Code öffnet und schließt die Verbindung nicht explizit. Die Fill-Methode öffnet implizit die Verbindung, die der DataAdapter verwendet, wenn er feststellt, dass die Verbindung noch nicht geöffnet ist. Wenn Fill die Verbindung geöffnet hat, wird die Verbindung auch geschlossen, wenn Fill abgeschlossen ist. Dies kann Ihren Code vereinfachen, wenn Sie einen einzelnen Vorgang ausführen, z. B. eine Füllung oder ein Update. Wenn Sie jedoch mehrere Vorgänge ausführen, für die eine offene Verbindung erforderlich ist, können Sie die Leistung Ihrer Anwendung verbessern, indem Sie die Open-Methode der Verbindung explizit aufrufen, die Vorgänge für die Datenquelle ausführen und anschließend die Close-Methode der Verbindung aufrufen. Sie sollten versuchen, die Verbindungen zur Datenquelle so kurz wie möglich offen zu halten, um Ressourcen für die Verwendung durch andere Clientanwendungen freizugeben.

Rick
quelle
Dies spricht die Frage überhaupt nicht an.
TylerH