如何从DataReader的当前行中获取DataRow

本文关键字:获取 DataRow DataReader | 更新日期: 2023-09-27 18:29:26

好的,我想从DataReader中提取一个DataRow。我已经四处寻找了很长一段时间,似乎没有一个简单的方法可以做到这一点。

我知道DataReader更像是行的集合,但它一次只读取一行。

所以我的问题是:有没有办法从DataReader的当前行中提取DataRow

如何从DataReader的当前行中获取DataRow

是否有任何方法可以从DataReader?

不,至少没有简单的方法。每个DataRow都属于一个表。不能将该属性留空,甚至不能更改表(不使用ImportRow)。

但是,如果您需要DataRows,为什么不首先填写DataTable呢?

DataTable table = new DataTable();
using(var con = new SqlConnection("...."))
using(var da = new SqlDataAdapter("SELECT ... WHERE...", con))
    da.Fill(table);
// now you have the row(s)

如果你真的需要从DataReader中获取行,你可以使用reader.GetSchemaTable来获取关于列的所有信息:

if (reader.HasRows)
{
    DataTable schemaTable = reader.GetSchemaTable();
    DataTable data = new DataTable();
    foreach (DataRow row in schemaTable.Rows)
    {
        string colName = row.Field<string>("ColumnName");
        Type t = row.Field<Type>("DataType");
        data.Columns.Add(colName, t);
    }
    while (reader.Read())
    {
        var newRow = data.Rows.Add();
        foreach (DataColumn col in data.Columns)
        {
            newRow[col.ColumnName] = reader[col.ColumnName];
        }
    }
}

但这并不是真正有效的。

您可能会问,因为您的DataReader代码看起来像这样:

static void ViaDataReader(IDataReader rdr)
{
    while (rdr.Read())
        Console.WriteLine("{0,-27} {1,-46} {2,-25} {3}", rdr[0], rdr[1], rdr[2], rdr[3]);
}
/// ...
ViaDataReader(DbProviderFactories.GetFactoryClasses().CreateDataReader());

但正如Tim所指出的,如果提前知道在每次迭代时都需要DataRow,那么应该使用DataTable,然后只迭代其Rows属性(以下输出与上面相同):

static void ViaDataTable(IDataReader rdr)
{
    var table = new DataTable();
    table.Load(rdr);
    foreach (DataRow row in table.Rows)
        Console.WriteLine("{0,-27} {1,-46} {2,-25} {3}", row[0], row[1], row[2], row[3]);
}
/// ...
ViaDataTable(DbProviderFactories.GetFactoryClasses().CreateDataReader());

如果出于某种原因必须继续使用DataReader,我想您可以在第一个示例中添加一个循环索引整数,然后在每次迭代中从(完全预加载的DataTable)中获取每一行。但由于DataTable的全面性更丰富,所以在完成DataTable.Load()之后,没有理由不放弃DataReader

我知道这是一个老问题,但我想我会投入我的两分钱。

首先,在我的案例中使用数据读取器的原因是我正在处理数百万行。

我对如何做到这一点的想法是;

While objDataReader.Read()
    Dim currentRow As DataRow
    Dim dt As New DataTable
    dt.Rows.Add(objDataReader)
    currentRow = dt.Rows(0)
    'Do processing...'
     dt = Nothing
     dt.Dispose()
End While
    

我刚刚将此代码添加到我的程序中。希望它能起作用。