Ich möchte DataTable mit DataReader füllen.
Ich habe ein Objekt wie folgt erstellt
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
{
}
Ich möchte DataTable mit DataReader füllen.
Ich habe ein Objekt wie folgt erstellt
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
{
}
Wenn Sie nur eine ReadOnly DataTable für Berichte oder das Web benötigen, können Sie dies versuchen:
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);
Ehre, wem Ehre gebührt: http://www.dotnetcurry.com/showarticle.aspx?ID=143
Sie können die Schema-Tabelle aus Ihrer SqlDataReader dr
um die Spaltennamen zu erhalten, speichern Sie die Namen in einer List<string>
und fügen Sie sie als Spalten in eine neue DataTable
, dann füllen Sie das DataTable
mit Indizierung auf dr
mit den Namen aus der 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;
Natürlich brauchen Sie Ihre try...catch...finally
Block um das Ganze herum, um Ausnahmen zu behandeln und Ihre Verbindung zu beenden, und verwenden Sie die letzte Bedingung nach der finally
. Ich fand dies hilfreich, um herauszufinden, wann ich Ergebnisse hatte und wann nicht, und um Probleme mit dt.Load(dr)
die fehlgeschlagen ist, als es keine Ergebnisse gab. ds.Fill(adapter)
war nicht viel besser, denn es schlug fehl, als ich versuchte, eine Tabelle mit 97 Spalten und etwa 80 Zeilen mit SELECT * FROM MyTable
. Nur der obige Code hat bei mir in allen Szenarien funktioniert.
Ursprünglich veröffentlicht am Datentabelle aus dem Datenleser befüllen von sarathkumar. Ich habe die Zusammenfassung zur Verfügung gestellt, sie komprimiert, die Null-Prüfungen und die Zuweisung, wenn es ein Null-Wert ist, hinzugefügt und die Tabelle in eine DataSet
und fügte die DataSet
Bedingung am Ende.
HINWEIS: Für diejenigen, die OracleDataReader
habe ich herausgefunden, dass ein Fehler auftreten kann, wenn Sie eine NCLOB
o CLOB
Feld, das in der Tabelle/Ergebnismenge, die Sie gerade lesen, null ist. Ich habe herausgefunden, dass ich für diese Spalte durch einen Blick auf den Index geprüft habe i
und hat dr.GetOracleClob(i)
anstelle von dr[i]
habe ich die Ausnahme nicht mehr erhalten. Siehe Antwort unter EF + ODP.NET + CLOB = Wert kann nicht Null sein - Parametername: byteArray? und ich habe diese Bedingung in den obigen Code eingefügt, wenn if (!dr.IsDBNull[i])
. Ähnlich verhält es sich, wenn Sie eine Null Decimal
Feld, musste ich es mit dr.GetFloat(i);
da weder dr.GetOracleDecimal(i);
y dr.GetDecimal(i);
schien einen Nullwert korrekt zu berücksichtigen.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.