Je souhaite remplir DataTable à l'aide de DataReader.Comment remplir un DataTable à l'aide de DataReader
J'ai créé objet comme celui-ci
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
{
}
Je souhaite remplir DataTable à l'aide de DataReader.Comment remplir un DataTable à l'aide de DataReader
J'ai créé objet comme celui-ci
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
{
}
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);
Je sais cela, je veux utiliser le lecteur de données – NoviceToDotNet
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
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);
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.
Connexes: http://stackoverflow.com/questions/18961938/populate-data-table-from-data-reader – vapcguy