HAVIT Knowledge Base

Vývoj webových aplikací, .NET, SQL, návrh
Welcome to HAVIT Knowledge Base Sign in | Join | Help
-
Home Články Forums Obrázky Soubory

.NET Framework

Microsoft .NET Framework, Base Class Library

Konverze SqlDataReaderu na DataSet

Ač to není příliš šťastná situace, může se nám někdy přihodit, že potřebujeme konvertovat SqlDataReader na DataSet.

V .NET Frameworku 1.1 jsou v podstatě dvě základní cesty - buď to udělat ručně, prvek po prvku, nebo si uvědomit, že DataAdapter dělá v podstatě totéž, a už by to tedy mohlo být někde řešeno (v .NET Frameworku 2.0 již je tato funkčnost exponováno prostřednictvím metody DataTable.Load(), viz níže).

Ručně to vypadá např. takto (kód není můj, tak to berte s rezervou):
public static DataSet DataReaderToDataSet( SqlDataReader rd )
{
    DataSet ds = new DataSet();
    do
    {
       DataTable st = rd.GetSchemaTable();
       DataTable Dt = new DataTable();
 
       if (st != null)
       {
          for (int i = 0 ; i < st.Rows.Count ; i++)
          {
             DataRow dr = st.Rows[i];
             string columnName = (string)dr["ColumnName"];
             DataColumn column = new DataColumn(columnName, (Type)dr["DataType"]);
             dt.Columns.Add(column);
          }
 
          ds.Tables.Add(dt);
 
          while (rd.Read())
          {
             DataRow dr = dt.NewRow();
 
             for (int i = 0; i < rd.FieldCount; i++)
                dr[i] = rd.GetValue(i);
 
             dt.Rows.Add(dr);
          }
       }
       else
       {
          DataColumn column = new DataColumn("RowsAffected");
          dt.Columns.Add(column);
          ds.Tables.Add(dt);
          DataRow dr = dt.NewRow();
          dr[0] = rd.RecordsAffected;
          dt.Rows.Add(dr);
       }
    }
    while (rd.NextResult());
 
    return ds;
}

Mnohem lepší fígl přes DataAdapter spočívá ve zjištění, že třída DbDataAdapter, z které jsou odvozeny všechny specifické DataAdaptery obsahuje metodu protected Fill(DataTable, IDataReader).

Můžeme tedy vytvořit vlastní DataAdapter odvozený od DbDataAdapteru, který tuto metodu použije ke zbudování příslušné tabulky:

public class DataReaderAdapter : DbDataAdapter

   public int FillFromReader(DataTable dataTable, IDataReader dataReader) 
   { 
      return this.Fill(dataTable, dataReader); 
   } 
   protected override RowUpdatedEventArgs CreateRowUpdatedEvent( 
      DataRow dataRow, 
      IDbCommand command, 
      StatementType statementType, 
      DataTableMapping tableMapping)
   {
      return null;
   } 
   protected override RowUpdatingEventArgs CreateRowUpdatingEvent( 
      DataRow dataRow, 
      IDbCommand command, 
      StatementType statementType, 
      DataTableMapping tableMapping)
   {
      return null;
   } 
   protected override void OnRowUpdated( 
      RowUpdatedEventArgs value)
   {
   } 
   protected override void OnRowUpdating( 
      RowUpdatingEventArgs value)
   {
   }
}

...a dát DataTable do DataSetu už není problém, případně escalovat SqlDataReader na další rowset a vytáhnout další tabulku. Ostatně DbDataAdapter obsahuje i mnoho další overloadů metody Fill() a můžeme si tak udělat mnohem chytřejší DataReaderAdapter.

Update pro .NET Framework 2.0

.NET Framework 2.0 již tuto problematiku řeší metodou DataTable.Load();

Published 8. května 2006 13:09 by Robert Haken
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

What do you think?

(required) 
(optional)
(required) 
Enter the code you see below

Submit