web-dev-qa-db-fra.com

Comment obtenir un DataRow sur la ligne actuelle d'un DataReader?

Ok, je voudrais extraire une DataRow une DataReader. Cela fait un certain temps que je regarde autour de moi et il ne semble pas qu'il existe un moyen simple de procéder.

Je comprends qu'une DataReader est plus une collection de lignes mais elle ne lit qu'une ligne à la fois.

Donc, ma question est la suivante: existe-t-il un moyen d’extraire une DataRow de la rangée actuelle d’une DataReader?

19
Rémi

Est-il possible d'extraire un DataRow de la ligne actuelle d'un DataReader?

Non, au moins pas simple. Chaque DataRow appartient à un Table . Vous ne pouvez pas laisser cette propriété vide, vous ne pouvez même pas modifier la table (sans utiliser ImportRow). 

Mais si vous avez besoin de DataRows, pourquoi ne remplissez-vous pas une DataTable en premier lieu?

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 vous avez vraiment besoin d'obtenir les lignes de la DataReader, vous pouvez utiliser reader.GetSchemaTable pour obtenir toutes les informations sur les colonnes:

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];
        }
    }
}

Mais ce n'est pas vraiment efficace.

24
Rango

Vous demandez probablement parce que vous avez le code DataReader qui ressemble à ceci:

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());

Mais comme Tim l’a fait remarquer, si vous savez à l'avance que vous allez vouloir la variable DataRow à chaque itération, vous devez utiliser DataTable à la place, puis simplement itérer sur sa propriété Rows au dessus de):

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 vous devez absolument continuer à utiliser la variable DataReader pour une raison quelconque, je suppose que vous pouvez ajouter un entier d'index de boucle à ce premier exemple, puis récupérer chaque ligne de la (variable DataTable entièrement chargée) de chaque itération. Mais puisque la DataTable est plus riche, il n’ya aucune raison de ne pas abandonner la DataReader après avoir effectué la DataTable.Load().

0
Glenn Slayden