【问题标题】:How do I extract data from a DataTable?如何从 DataTable 中提取数据?
【发布时间】:2010-11-23 16:28:01
【问题描述】:

我有一个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 中的数据提取到有意义的表单中?

【问题讨论】:

    标签: c# sql ado.net


    【解决方案1】:

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

    【讨论】:

    • 我知道这是一个旧答案,但是您不需要在 foreach 循环中进行强制转换以允许索引吗?在将代码更改为如下所示之前,我无法执行此类操作: foreach(DataRow row in YourDataTable.Rows.Cast()) ...
    • 甚至更早的评论,但无需强制转换:foreach 有效,因为Rows 是一个集合 (DataRowCollection)。不过,如果你想使用一些 Linq 方法(例如.Where()),你需要使用.Cast<DataRow>()
    【解决方案2】:

    您可以将数据表设置为许多元素的数据源。

    例如

    网格视图

    中继器

    数据列表

    等等等等

    如果您需要从每一行中提取数据,那么您可以使用

    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)table.Rows
    【解决方案3】:

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

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

    来自MSDNField&lt;T&gt; 方法:

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

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

    例如:

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

      【讨论】:

        【解决方案5】:

        除非您有特定的理由使用原始 ado.net,否则我会考虑使用 ORM(对象关系映射器),如 nHibernate 或 LINQ to SQL。这样您就可以查询数据库并检索要使用的对象,这些对象是强类型且更易于使用恕我直言。

        【讨论】:

        【解决方案6】:
          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);
                 }
             }
        

        【讨论】:

        • 这个答案将受益于解释。从长远来看,只有代码的答案很少有用。
        【解决方案7】:

        请注意,使用 DataAdapter 时不需要打开和关闭连接。

        所以我建议请更新此代码并删除连接的打开和关闭:

                SqlDataAdapter adapt = new SqlDataAdapter(cmd);
        

        conn.Open(); // 这行代码是多余的

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

        conn.Close(); // 这行代码是多余的

                Console.WriteLine("connection closed successfuly");
        

        Reference Documentation

        此示例中显示的代码没有显式打开和关闭 联系。 Fill 方法隐式打开连接 如果 DataAdapter 发现尚未建立连接,则正在使用 打开。如果 Fill 打开了连接,它也会关闭连接 填充完成时。这可以在您处理时简化您的代码 单个操作,例如填充或更新。但是,如果你是 执行需要打开连接的多个操作,您 可以通过显式调用来提高应用程序的性能 Connection 的 Open 方法,执行针对的操作 数据源,然后调用 Connection 的 Close 方法。 您应该尝试保持与数据源的连接尽可能短暂地打开 尽可能释放资源供其他客户端应用程序使用。

        【讨论】:

        • 这根本没有解决问题。
        猜你喜欢
        • 1970-01-01
        • 2019-07-02
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多