如何从DataTable中提取数据?

95

我有一个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 中提取数据,并将其转换为有意义的形式以供使用?

7个回答

186

DataTable有一个DataRow元素的集合.Rows

每个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 row in YourDataTable.Rows.Cast<DataRow>())... - awh112
1
即使是较旧的评论,也没有必要进行强制转换:foreach可以工作,因为Rows是一个集合(DataRowCollection)。但是,如果您想使用一些Linq方法(例如.Where()),则需要使用.Cast<DataRow>() - Anderson Pimentel

27

你可以将数据表设置为许多元素的数据源.

例如

gridView

repeater

datalist

等等

如果需要从每行提取数据,则可以使用

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 dr in table )table.Rows - StampedeXV

12

在您有多种数据类型(而不仅仅是字符串)时,从 DataTable 中提取数据的最简单方法是使用 System.Data.DataSetExtensions 程序集中提供的 Field<T> 扩展方法。

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

来自MSDNField<T>方法:

提供对数据行中每个列值的强类型访问。

这意味着当您指定类型时,它将验证并拆箱对象。

例如:

// 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 提取数据的过程,因为它消除了需要显式转换或解析对象为正确类型的需求。


6
请考虑使用以下代码:

请考虑使用以下代码:

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

除非您有特定的原因要使用原始ado.net,否则我建议使用ORM(对象关系映射器),例如nHibernate或LINQ to SQL。这样,您可以查询数据库并检索强类型的对象进行操作,这样更易于操作。


1
在按照https://dev59.com/G3M_5IYBdhLWcg3wgzhl#1345531的建议之前,我正在学习ADO.net的基础知识,然后再转向ORM。 - 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
这个答案需要解释才能更有价值。仅有代码的答案很少在长期内有用。 - TylerH

-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正在使用的连接。如果Fill打开了连接,则在Fill完成时也会关闭连接。当您处理单个操作(例如填充或更新)时,这可以简化您的代码。但是,如果您执行需要打开连接的多个操作,则可以通过显式调用Connection的Open方法、执行针对数据源的操作,然后调用Connection的Close方法来提高应用程序的性能。您应该尽可能短暂地保持与数据源的连接打开,以释放资源供其他客户端应用程序使用。


这完全没有回答问题。 - TylerH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接