c# - oracledatareader - sqldatareader to datatable
¿Cómo obtener un DataRow de la fila actual de un DataReader? (2)
¿Hay alguna manera de extraer un DataRow de la fila actual de un DataReader?
No, al menos no de manera sencilla. Cada DataRow pertenece a una Table . No puede dejar esa propiedad vacía, ni siquiera puede cambiar la tabla (sin usar ImportRow).
Pero si necesita DataRows, ¿por qué no llena una DataTable
en primer lugar?
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)
Si realmente necesita obtener las filas del DataReader
, puede usar reader.GetSchemaTable
para obtener toda la información sobre las columnas:
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];
}
}
}
Pero eso no es realmente eficiente.
Ok, me gustaría extraer un DataRow
un DataReader
. He estado mirando a mi alrededor por bastante tiempo y no parece que haya una manera simple de hacer esto.
Entiendo que un DataReader
es más una colección de filas pero solo lee una fila a la vez.
Entonces, mi pregunta: ¿hay alguna manera de extraer un DataRow
la fila actual de un DataReader
?
Probablemente estés preguntando porque tienes un código DataReader
que se parece a esto:
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());
Pero como Tim señaló, si sabe de antemano que va a querer el DataRow
en cada iteración, debe usar DataTable
lugar, y luego simplemente iterar en su propiedad Rows
(la siguiente salida es idéntica a la anterior):
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());
Si por alguna razón debe continuar usando el DataReader
, supongo que podría agregar un entero de índice de bucle a ese primer ejemplo, y luego tomar cada fila de ( DataTable
completamente cargada) en cada iteración. Pero como el DataTable
es más completo, no hay razón para no abandonar el DataReader
después de hacer el DataTable.Load()
.