2009-08-28 23 views
47

Mam DataTable, który jest wypełniany z kwerendy SQL do lokalnej bazy danych, ale nie wiem, jak wyodrębnić dane z niego. Główne metody (w programie badania):Jak wyodrębnić dane z DataTable?

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(); 
} 

Komenda użyłem do stworzenia tabel w mojej bazy danych:

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

Jak można wyodrębnić dane z DataTable w postaci znaczącego w użyciu?

Odpowiedz

115

DataTable ma kolekcja .Rows elementów DataRow.

Każdy rekord DataRow odpowiada jednemu wierszowi w bazie danych i zawiera zbiór kolumn.

W celu uzyskania dostępu do pojedynczej wartości, czy coś w tym rodzaju:

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

+2

wiem, że to jest stary odpowiedź, ale czy nie trzeba zrobić odlew w pętli foreach, aby umożliwić indeksowanie? Nie mogłem zrobić czegoś takiego, dopóki nie zmieniłem kodu, aby wyglądać tak: foreach (wiersz DataRow w YourDataTable.Rows.Cast ()) ... – awh112

+0

Jeszcze starszy komentarz, ale nie ma potrzeby do rzutowania: 'foreach' działa, ponieważ' Wiersze' to kolekcja ('DataRowCollection'). Chociaż musisz użyć '.Cast ()' jeśli chcesz użyć niektórych metod Linq ('.Where()', na przykład). –

+1

@marc_s Dziękuję –

16

Można ustawić datatable jako źródło danych dla wielu elementów.

Np

GridView

repeater

datalist

etc etc

Jeśli trzeba wyodrębnić dane z każdego wiersza, a następnie można użyć

table.rows[rowindex][columnindex] 

lub

jeśli znasz nazwę kolumny

table.rows[rowindex][columnname] 

Jeśli trzeba iteracyjne tabelę następnie można użyć pętli for lub pętli foreach jak

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(); 
} 
+0

foreach (DataRow dr w tabeli) table.Rows – StampedeXV

3

Chyba że masz konkretny powód do surowego ADO.NET musiałbym spojrzeć na użyciu ORM (obiektowy program odwzorowujący relację), taki jak nhibernate lub Linq do Sql. W ten sposób można przeszukiwać bazę danych i retreive obiektów do pracy, które są mocno wpisane i łatwiej pracować z IMHO.

Colin G

+1

Mam podstawową wiedzę na temat ADO.net przed przejściem do ORM zgodnie z sugestią http://stackoverflow.com/questions/1345508/how-do-i-connect-toa-a- sql-database-from-c/1345531 # 1345531 – RCIX

4

Proszę rozważyć użycie kodu tak:

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(); 
0
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); 
     } 
    } 
0

Proszę pamiętać, że otwierają się i zamykają połączenie nie jest konieczne przy korzystaniu DataAdapter.

więc proponuję zaktualizuj ten kod i usunąć otwierać i zamykać połączenia:

 SqlDataAdapter adapt = new SqlDataAdapter(cmd); 

conn.Open(); // linia kodu uncessessary

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

conn.Close(); // ta linia kodu jest uncessessary

 Console.WriteLine("connection closed successfuly"); 

Reference Documentation

Kod pokazany w tym przykładzie wyraźnie nie otwierać i zamykać połączenia . Metoda wypełniania powoduje niejawne otwarcie połączenia, które jest używane przez DataCheck, gdy wykryje, że połączenie nie jest już otwarte . Jeśli wypełnienie Fill otworzy połączenie, po zakończeniu wypełniania zostanie również zamknięte połączenie . Może to uprościć twój kod, gdy masz do czynienia z pojedynczą operacją, taką jak Wypełnienie lub Aktualizacja. Jeśli jednak wykonujesz wiele operacji wymagających połączenia otwartego, możesz poprawić wydajność swojej aplikacji, jawnie wywołując metodę Open połączenia, wykonując operacje na źródła danych, a następnie wywołując metodę Close połączenia. Powinieneś starać się utrzymywać połączenia ze źródłem danych tak krótko, jak to tylko możliwe, aby uzyskać wolne zasoby do użycia przez inne aplikacje klienckie.