Как получить DataRow из текущей строки DataReader?


Хорошо, я хотел бы извлечь a DataRow из A DataReader. Я уже довольно долго оглядываюсь вокруг, и не похоже, что есть простой способ сделать это.

Я понимаю, что DataReader - это скорее набор строк, но он читает только одну строку одновременно.

Итак, мой вопрос: есть ли способ извлечь a DataRow из текущей строки a DataReader?

2 19

2 ответа:

Есть ли способ, чтобы извлечь Строкаданных из текущей строке DataReader ?

Нет, по крайней мере, не простой способ. Каждый DataRow принадлежит одной таблице . Вы не можете оставить это свойство пустым, вы даже не можете изменить таблицу (без использования ImportRow).

Но если вам нужны потоки данных, почему бы вам не заполнить 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());

Но, как указал Тим, если Вы заранее знаете , что вам понадобится 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 богаче всех вокруг, нет никакой причины не отказаться от DataReader после выполнения DataTable.Load().