2010-11-03 20 views

Répondre

0

Pour remplir un DataSet, vous pouvez utiliser quelque chose comme:

var da = new SqlDataAdapter(); 
da.SelectCommand = cmd; // your SqlCommand object 
var ds = new DataSet(); 
da.Fill(ds); 
+0

Je sais cela, je veux utiliser le lecteur de données – NoviceToDotNet

9

Si tout ce que vous voulez est un DataTable ReadOnly pour les rapports ou sur le Web, essayer :

conn = new SqlConnection(connString); 
    string query = "SELECT * FROM Customers"; 
    SqlCommand cmd = new SqlCommand(query, conn); 
    conn.Open(); 
    SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
    DataTable dt = new DataTable(); 
    dt.Load(dr); 

crédit où il est dû: http://www.dotnetcurry.com/showarticle.aspx?ID=143

2

DataTable.load() peut être utilisé pour une approche générique.

do { 
    var table = new DataTable(); 
    table.Load(reader); 
    dataset.Tables.Add(table); 
} while(!reader.IsClosed); 
1

Vous pouvez obtenir le tableau de schéma de votre SqlDataReader dr pour obtenir les noms de colonnes, enregistrer les noms à un List<string> et les ajouter sous forme de colonnes sur une nouvelle DataTable, puis remplir ce DataTable en utilisant l'indexation sur dr avec les noms de la liste:

DataSet ds = new DataSet(); 
DataTable dtSchema = dr.GetSchemaTable(); 
DataTable dt = new DataTable(); 
List<DataColumn> listCols = new List<DataColumn>(); 
List<DataColumn> listTypes = new List<DataColumn>(); 

if (dtSchema != null) 
{ 
    foreach (DataRow drow in dtSchema.Rows) 
    { 
     string columnName = System.Convert.ToString(drow["ColumnName"]); 
     DataColumn column = new DataColumn(columnName, (Type)(drow["DataType"])); 
     listCols.Add(column); 
     listTypes.Add(drow["DataType"].ToString()); // necessary in order to record nulls 
     dt.Columns.Add(column); 
    } 
} 

// Read rows from DataReader and populate the DataTable 
if (dr.HasRows) 
{ 
    while (dr.Read()) 
    {    
     DataRow dataRow = dt.NewRow(); 
     for (int i = 0; i < listCols.Count; i++) 
     { 
      if (!dr.IsDBNull[i]) 
      { 
       // If your query will go against a table with null CLOB fields 
       // and that column is the 5th column... 
       if (strSQL == "SELECT * FROM TableWithNullCLOBField" && i == 4) 
        dataRow[((DataColumn)listCols[i])] = dr.GetOracleClob(i).Value; 
       // If you might have decimal values of null... 
       // I found dr.GetOracleDecimal(i) and dr.GetDecimal(i) do not work 
       else if (listTypes[i] == System.Decimal) 
        dataRow[((DataColumn)listCols[i])] = dr.GetFloat(i);     
       else 
        dataRow[((DataColumn)listCols[i])] = dr[i]; // <-- gets index on dr 
      } 
      else // value was null 
      { 
       byte[] nullArray = new byte[0]; 
       switch (listTypes[i]) 
       { 
        case "System.String": 
         dataRow[((DataColumn)listCols[i])] = String.Empty; 
        break; 
        case "System.Decimal": 
        case "System.Int16": // Boolean 
        case "System.Int32": // Number 
         dataRow[((DataColumn)listCols[i])] = 0; 
        break; 
        case "System.DateTime": 
         dataRow[((DataColumn)listCols[i])] = DBNull.Value; 
        break; 
        case "System.Byte[]": // Blob 
         dataRow[((DataColumn)listCols[i])] = nullArray; 
        break; 
        default: 
         dataRow[((DataColumn)listCols[i])] = String.Empty; 
        break; 
       } 
      } 
     } 
     dt.Rows.Add(dataRow); 
    } 
    ds.Tables.Add(dt); 
} 

// Put this after everything is closed 
if (ds.Tables.Count > 0) 
    return ds.Tables[0]; // there should only be one table if we got results 
else 
    return null; 

il est évident que vous aurez besoin de votre bloc autour try...catch...finally tout pour gérer les exceptions et la disposition de votre connexion et utiliser la dernière condition après la finally. J'ai trouvé cela utile pour savoir quand j'ai eu des résultats ou non, et j'ai évité les problèmes avec dt.Load(dr) qui échouaient quand il n'y avait pas de résultats. ds.Fill(adapter) n'était pas beaucoup mieux, car il a échoué quand j'ai essayé d'attraper une table de 97 colonnes et environ 80 lignes avec SELECT * FROM MyTable. Seul le code ci-dessus a réussi à fonctionner dans tous les scénarios, pour moi.

Publié à l'origine le Populate data table from data reader par sarathkumar. J'ai fourni le résumé, l'ai condensé, ajouté les vérifications nuls et assigné si c'est une valeur nulle, et ajouté la table à un DataSet et ajouté la condition DataSet à la fin.

REMARQUE: Pour ceux qui utilisent OracleDataReader, je trouve que vous pouvez rencontrer une erreur si vous avez un champ NCLOB ou CLOB qui est nulle dans le tableau/jeu de résultats que vous lisez. J'ai trouvé si j'ai vérifié pour cette colonne en regardant l'index i et ai fait dr.GetOracleClob(i) au lieu de dr[i], j'ai cessé d'obtenir l'exception. Voir la réponse à EF + ODP.NET + CLOB = Value Cannot be Null - Parameter name: byteArray? et j'ai ajouté cette condition dans le code ci-dessus lorsque if (!dr.IsDBNull[i]). De même, si vous avez un champ Decimal nul, je devais le vérifier avec dr.GetFloat(i);, puisque ni dr.GetOracleDecimal(i); ni dr.GetDecimal(i); ne semblaient contenir correctement une valeur nulle.

Questions connexes