如何使用DataReader填充DataTable

时间:2010-11-03 16:52:25

标签: asp.net ado.net sqldatareader

我想使用DataReader填充DataTable。

我创建了像这样的对象

SqlDataReader dr = cmd.ExecuteReader();

if(dr.HasRows)
{

}

4 个答案:

答案 0 :(得分:13)

如果你想要的只是一个用于报告或网络的ReadOnly DataTable,请试试这个:

  conn = new SqlConnection(connString);
  string query = "SELECT * FROM Customers";
  SqlCommand cmd = new SqlCommand(query, conn);
  conn.Open();
  SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
  DataTable dt = new DataTable();
  dt.Load(dr);

信用到期日:http://www.dotnetcurry.com/showarticle.aspx?ID=143

答案 1 :(得分:3)

DataTable.load()可用于通用方法。

do {
    var table = new DataTable();
    table.Load(reader);
    dataset.Tables.Add(table);
} while(!reader.IsClosed);

答案 2 :(得分:2)

您可以从SqlDataReader dr获取架构表以获取列名,将名称保存到List<string>并将其添加为新DataTable上的列,然后填写{ {1}}在DataTable上使用列表中的名称进行索引:

dr

显然,您需要围绕这一切DataSet ds = new DataSet(); DataTable dtSchema = dr.GetSchemaTable(); DataTable dt = new DataTable(); List<DataColumn> listCols = new List<DataColumn>(); List<DataColumn> listTypes = new List<DataColumn>(); if (dtSchema != null) { foreach (DataRow drow in dtSchema.Rows) { string columnName = System.Convert.ToString(drow["ColumnName"]); DataColumn column = new DataColumn(columnName, (Type)(drow["DataType"])); listCols.Add(column); listTypes.Add(drow["DataType"].ToString()); // necessary in order to record nulls dt.Columns.Add(column); } } // Read rows from DataReader and populate the DataTable if (dr.HasRows) { while (dr.Read()) { DataRow dataRow = dt.NewRow(); for (int i = 0; i < listCols.Count; i++) { if (!dr.IsDBNull[i]) { // If your query will go against a table with null CLOB fields // and that column is the 5th column... if (strSQL == "SELECT * FROM TableWithNullCLOBField" && i == 4) dataRow[((DataColumn)listCols[i])] = dr.GetOracleClob(i).Value; // If you might have decimal values of null... // I found dr.GetOracleDecimal(i) and dr.GetDecimal(i) do not work else if (listTypes[i] == System.Decimal) dataRow[((DataColumn)listCols[i])] = dr.GetFloat(i); else dataRow[((DataColumn)listCols[i])] = dr[i]; // <-- gets index on dr } else // value was null { byte[] nullArray = new byte[0]; switch (listTypes[i]) { case "System.String": dataRow[((DataColumn)listCols[i])] = String.Empty; break; case "System.Decimal": case "System.Int16": // Boolean case "System.Int32": // Number dataRow[((DataColumn)listCols[i])] = 0; break; case "System.DateTime": dataRow[((DataColumn)listCols[i])] = DBNull.Value; break; case "System.Byte[]": // Blob dataRow[((DataColumn)listCols[i])] = nullArray; break; default: dataRow[((DataColumn)listCols[i])] = String.Empty; break; } } } dt.Rows.Add(dataRow); } ds.Tables.Add(dt); } // Put this after everything is closed if (ds.Tables.Count > 0) return ds.Tables[0]; // there should only be one table if we got results else return null; 阻止处理异常并处理您的连接,并使用try...catch...finally之后的最后一个条件。我发现这很有帮助,以便在我有结果时找出结果,并避免在没有结果时失败的finally问题。 dt.Load(dr)并没有好多少,因为当我尝试使用ds.Fill(adapter)抓取97列和大约80行的表时失败了。对我来说,只有上面的代码可以在所有场景中使用。

最初由sarathkumar发布在Populate data table from data reader上。我提供了摘要,压缩了它,添加了空检查并分配了它是否为空值,并将表添加到SELECT * FROM MyTable并在最后添加了DataSet条件。

注意:对于使用DataSet的用户,我发现如果您在表/结果集中有OracleDataReaderNCLOB字段为空,则可能会遇到错误正在读书。我发现如果通过查看索引CLOB检查了该列并且i而不是dr.GetOracleClob(i),我就停止了获取异常。请参阅EF + ODP.NET + CLOB = Value Cannot be Null - Parameter name: byteArray?上的回答,并在dr[i]时在上面的代码中添加了此条件。同样,如果您有一个空if (!dr.IsDBNull[i])字段,我必须使用Decimal进行检查,因为dr.GetFloat(i);dr.GetOracleDecimal(i);似乎都没有正确容纳空值。

答案 3 :(得分:0)

要填写DataSet,您可以使用以下内容:

var da = new SqlDataAdapter();
da.SelectCommand = cmd; // your SqlCommand object
var ds = new DataSet();
da.Fill(ds);