我想使用DataReader填充DataTable。如何使用DataReader填充DataTable
我创建对象这样
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
{
}
我想使用DataReader填充DataTable。如何使用DataReader填充DataTable
我创建对象这样
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
{
}
来一补DataSet
,您可以使用类似:
var da = new SqlDataAdapter();
da.SelectCommand = cmd; // your SqlCommand object
var ds = new DataSet();
da.Fill(ds);
我知道这一点,我想使用datareader – NoviceToDotNet 2010-11-03 17:00:19
如果你想要的是一个只读数据表用于报告或网页,试试这个:
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);
DataTable.load()可用于通用方法。
do {
var table = new DataTable();
table.Load(reader);
dataset.Tables.Add(table);
} while(!reader.IsClosed);
你可以从你SqlDataReader dr
获取架构表得到的列名,名称保存到List<string>
并将其添加为列上了一个新DataTable
,然后填写,使用索引上dr
从名字DataTable
名单:
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行左右的SELECT * FROM MyTable
时,它失败了。只有上面的代码才能在所有场景下工作,对我来说。
最初发布在Populate data table from data reader由sarathkumar。我提供了摘要,精简了它,添加了空检查并分配它是否为空值,并将该表添加到DataSet
并在最后添加了DataSet
条件。
注意:对于那些使用OracleDataReader
,我发现如果您正在阅读的表/结果集中有一个空值为NCLOB
或CLOB
的字段,则会发生错误。我发现如果我通过查看索引i
并确定dr.GetOracleClob(i)
而不是dr[i]
来检查该列,我停止了解例外。请参阅EF + ODP.NET + CLOB = Value Cannot be Null - Parameter name: byteArray?的答案,并在if (!dr.IsDBNull[i])
时在上面的代码中添加了此条件。同样,如果您的空字段为Decimal
,则必须使用dr.GetFloat(i);
进行检查,因为dr.GetOracleDecimal(i);
和dr.GetDecimal(i);
似乎都无法正确适应空值。
相关:http://stackoverflow.com/questions/18961938/populate-data-table-from-data-reader – vapcguy 2016-11-17 19:31:12