C# - SqlDataReader adatainak konvertálása DataSet-be

forráskód letöltése
Ha egy lekérdezést az SqlDataReader segítségével futtatunk, de mégis szükségünk lenne arra, hogy az eredmény DataTable formájában is rendelkezésre álljon, akkor nagy segítséget nyújt az e példában létrehozott függvény. Mivel egy-egy lekérdezés több DataTable-t is eredményezhet, így függvényünk egy DataSet osztályt hoz létre az SqlDataReader-ből, mely tetszőleges számú DataTable-t tartalmazhat.
A készítendő függvényt DataReaderToDataSet névvel hozzuk létre. Paraméterként egy SqlDataReader osztályt vár, melyből elkészíti a DataSet-et, annyi DataTable-t elhelyezve benne, amennyire csak szükség van. Visszatérési értékként ezt a DataSet-et adja.
    public static DataSet DataReaderToDataSet(SqlDataReader dr)
    {
      DataSet dataSet = new DataSet();
A DataSet létrehozása után egy do - while ciklust kezdeményezünk, mellyel végigmegyünk a kapott adathalmazokon. Minden adathalmaz egy-egy DataTable-nek felel meg.
      do
      {
Első lépésként meg kell határoznunk, hogy milyen típusú oszlopokat kell létrehoznunk az adattáblához. Ehhez a GetSchemaTable függvényt hívjuk meg. Ez eredményül egy DataTable-t ad, melyben a létrehozandó adattábla oszlopainak leírása található.
        DataTable schemaTable = dr.GetSchemaTable();
Létrehozunk most egy üres DataTable-t, melybe egy ciklussal felvesszük a szükséges oszlopokat.
        DataTable dataTable = new DataTable();
        if (schemaTable!=null)
        {
          for (int i=0; i<schemaTable.Rows.Count; i++)
          {
            DataRow dataRow = schemaTable.Rows[i];
            string columnName = (string)dataRow["ColumnName"]; 
            DataColumn column = new DataColumn(columnName, (Type)dataRow["DataType"]);
            dataTable.Columns.Add(column);
          }
Most már rendelkezésünkre áll egy megfelelő típusokkal rendelkező adattábla, melyet rögtön a DataSet-hez is adunk. Egy while ciklussal kiolvassuk az összes sort az SqlDataReader-ből.
          dataSet.Tables.Add(dataTable);
          while (dr.Read())
          {
Minden sornál egy DataRow osztályba töltjük az egyes oszlopok adatait, melyeken egy for ciklussal megyünk végig.
            DataRow dataRow = dataTable.NewRow();
            for (int i=0; i<dr.FieldCount; i++)
            {
              dataRow[i] = dr.GetValue(i);
            }
Végül a sort hozzáadjuk a már létrehozott DataTable-hoz.
            dataTable.Rows.Add(dataRow);
          }
        }
Előfordulhat olyan eset is, amikor nem kapunk eredményt a GetSchemaTable függvény által. Ez akkor történhet, amikor a lekérdezést mondjuk az ExecuteScalar-al futtatjuk. Ilyen esetben csupán egyetlen oszlopunk és egyetlen sorunk lesz, ezt kell csak a táblához adnunk.
        else
        {
          DataColumn column = new DataColumn("RowsAffected");
          dataTable.Columns.Add(column);
          dataSet.Tables.Add(dataTable);
          DataRow dataRow = dataTable.NewRow();
          dataRow[0] = dr.RecordsAffected;
          dataTable.Rows.Add(dataRow);
        }
      }
      while (dr.NextResult());
      return dataSet;
    }
A függvény kipróbálásához futtatunk egy olyan lekérdezést, melyben két különböző select található. Ennek eredménye két különböző adattábla lesz.
    private void button1_Click(object sender, System.EventArgs e)
    {
      ...
      SqlCommand c = new SqlCommand("select * from products; select * from orders", connection);
A lekérdezést az ExecuteReader függvény hívásával futtatjuk, majd az eredményül kapott SqlDataReader osztályt konvertáljuk a függvényünkkel DataSet-té.
      SqlDataReader dr = c.ExecuteReader();
      DataSet ds = DataReaderToDataSet(dr);
Ezt követően a két táblát hozzákötjük egy-egy DataGrid-hez, hogy az eredmény látható is legyen.
      dataGrid1.DataSource = ds.Tables[0].DefaultView;
      dataGrid2.DataSource = ds.Tables[1].DefaultView;
      connection.Close();
    }