【问题标题】:How to get a DataRow out the current row of a DataReader?如何从 DataReader 的当前行中获取 DataRow?
【发布时间】:2013-09-01 22:21:18
【问题描述】:

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

我知道DataReader 更多的是行的集合,但它当时只读取一行。

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

【问题讨论】:

  • “DataReader 更像是行的集合” 不,它更像是对单个记录的视图。 DataReader 是数据库中记录的只进流。您只能查看当前记录。

标签: c# datarow datareader


【解决方案1】:

有什么方法可以从当前行中提取 DataRow 数据读取器?

不,至少没有简单的方法。每个 DataRow 都属于一个 Table。您不能将该属性留空,甚至不能更改表(不使用 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 比填充DataTable 然后将它与另一个DataTable 中的其他行合并更好
  • 您的编辑带来了很好的观点。它看起来并不比用单行填充DataTable 并比之后合并更好。如果它不能完全回答我的问题,我将标记为回答事件。
  • @im_a_noob:请注意,我现在已经测试了代码并编辑了第二部分。
【解决方案2】:

您可能会问,因为您的 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

【讨论】:

  • 我不会这么快就建议使用 DataTable。 DataReader 比 DataTable/DataRow 有一个巨大的优势,后者将整个结果保存在内存中,而前者只保存一行。
猜你喜欢
  • 1970-01-01
  • 2010-12-21
  • 2011-09-11
  • 1970-01-01
  • 2016-12-16
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多