Як отримати дані з таблиці даних?


78

У мене є DataTableте, що заповнюється із запиту SQL до локальної бази даних, але я не знаю, як витягти з нього дані. Основний метод (у тестовій програмі):

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

Команда, яку я використовував для створення таблиць у своїй базі даних:

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

Як я можу витягти дані з DataTableу форму, значущу для використання?

Відповіді:


157

DataTable має колекцію .Rowsелементів DataRow.

Кожен DataRow відповідає одному рядку у вашій базі даних і містить набір стовпців.

Щоб отримати доступ до одного значення, зробіть щось подібне:

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

2
Я знаю, що це стара відповідь, але чи не потрібно робити привід у циклі foreach, щоб дозволити індексацію? Я не зміг зробити щось подібне, поки не змінив код, щоб виглядати таким: foreach (рядок DataRow у YourDataTable.Rows.Cast <DataRow> ()) ...
awh112

1
Ще старіший коментар, але немає потреби кидати: foreachworks, тому що Rowsце колекція ( DataRowCollection). Хоча, вам потрібно використовувати, .Cast<DataRow>()якщо ви хочете використовувати деякі методи Linq (наприклад .Where(), для прикладу).
Андерсон Піментел

24

Ви можете встановити таблицю даних як джерело даних для багатьох елементів.

Наприклад,

gridView

ретранслятор

даталіст

тощо тощо

Якщо вам потрібно витягти дані з кожного рядка, тоді ви можете використовувати

table.rows[rowindex][columnindex]

або

якщо ви знаєте назву стовпця

table.rows[rowindex][columnname]

Якщо вам потрібно повторити таблицю, ви можете використовувати цикл for або foreach, наприклад

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

Таблиця foreach (DataRow в таблиці). Рядки
StampedeXV

7

Найпростіший спосіб вилучення даних із, DataTableколи у вас кілька типів даних (а не лише рядки), - це використання Field<T>методу розширення, доступного в System.Data.DataSetExtensionsзбірці.

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

З MSDN , по Field<T>методу:

Забезпечує строко набраний доступ до кожного зі значень стовпців у DataRow.

Це означає, що коли ви вкажете тип, він перевірить і розпакує об'єкт.

Наприклад:

// 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
}

Він також підтримує типи, що допускають обнулення:

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

Це може спростити вилучення даних, DataTableоскільки усуває необхідність явного перетворення або синтаксичного аналізу об’єкта на правильні типи.


4

Будь ласка, розгляньте можливість використання такого коду:

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

3

Якщо у вас немає конкретної причини робити raw ado.net, я б подивився на використання ORM (об'єктний реляційний картограф), такий як nHibernate або LINQ to SQL. Таким чином, ви можете запитувати базу даних і отримувати об’єкти, для роботи з якими набрано сильніше і простіше працювати з IMHO.


1
Я отримую базові знання ADO.net , перш ніж перейти до ОРЗ , як було запропоновано stackoverflow.com/questions/1345508 / ...
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);
         }
     }

Ця відповідь мала б користь від пояснення. Відповіді лише на коди рідко корисні в довгостроковій перспективі.
ТайлерН

-1

Зверніть увагу, що відкривати та закривати з'єднання не потрібно під час використання DataAdapter.

Тому я пропоную оновити цей код і видалити відкриття та закриття з’єднання:

        SqlDataAdapter adapt = new SqlDataAdapter(cmd);

conn.Open (); // цей рядок коду є необхідним

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

conn.Close (); // цей рядок коду є необхідним

        Console.WriteLine("connection closed successfuly");

Довідкова документація

Код, показаний у цьому прикладі, явно не відкриває та не закриває підключення. Метод Fill неявно відкриває підключення, яке використовує DataAdapter, якщо виявляє, що підключення ще не відкрите. Якщо заповнення відкрило з'єднання, воно також закриває з'єднання після завершення заповнення. Це може спростити ваш код, коли ви маєте справу з однією операцією, такою як заповнення або оновлення. Однак, якщо ви виконуєте кілька операцій, які вимагають відкритого з'єднання, ви можете покращити продуктивність своєї програми, явно викликавши метод Відкритого з'єднання, виконавши операції щодо джерела даних, а потім викликавши метод Закрити з'єднання. Вам слід намагатися тримати зв’язки з джерелом даних якомога коротше відкритими, щоб звільнити ресурси для використання іншими клієнтськими програмами.


Це взагалі не стосується питання.
TylerH
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.