Comment changer le type de données D'une DataColumn dans un DataTable?
J'ai:
DataTable Table = new DataTable;
SqlConnection = new System.Data.SqlClient.SqlConnection("Data Source=" + ServerName + ";Initial Catalog=" + DatabaseName + ";Integrated Security=SSPI; Connect Timeout=120");
SqlDataAdapter adapter = new SqlDataAdapter("Select * from " + TableName, Connection);
adapter.FillSchema(Table, SchemaType.Source);
adapter.Fill(Table);
DataColumn column = DataTable.Columns[0];
Ce que je veux faire est:
Supposons actuellement colonne.Type de données.Nom est "Double". Je veux qu'il devienne "Int32".
Comment puis-je y parvenir?
10 réponses
Vous ne pouvez pas modifier le type de données après que le Datatable est rempli de données. Cependant, vous pouvez cloner la table de données, modifier le type de colonne et charger les données de la table de données précédente à la table clonée comme indiqué ci-dessous.
DataTable dtCloned = dt.Clone();
dtCloned.Columns[0].DataType = typeof(Int32);
foreach (DataRow row in dt.Rows)
{
dtCloned.ImportRow(row);
}
S'il est vrai que vous ne pouvez pas changer le type de la colonne après que le DataTable
est rempli, vous pouvez le changer après avoir appelé FillSchema
, mais avant d'appeler Fill
. Par exemple, disons que la 3ème colonne est celle que vous voulez convertir de double
à Int32
, vous pouvez utiliser:
adapter.FillSchema(table, SchemaType.Source);
table.Columns[2].DataType = typeof (Int32);
adapter.Fill(table);
Ancien post, mais je pensais peser, avec une extension DataTable qui peut convertir une seule colonne à la fois, à un type donné:
public static class DataTableExt
{
public static void ConvertColumnType(this DataTable dt, string columnName, Type newType)
{
using (DataColumn dc = new DataColumn(columnName + "_new", newType))
{
// Add the new column which has the new type, and move it to the ordinal of the old column
int ordinal = dt.Columns[columnName].Ordinal;
dt.Columns.Add(dc);
dc.SetOrdinal(ordinal);
// Get and convert the values of the old column, and insert them into the new
foreach (DataRow dr in dt.Rows)
dr[dc.ColumnName] = Convert.ChangeType(dr[columnName], newType);
// Remove the old column
dt.Columns.Remove(columnName);
// Give the new column the old column's name
dc.ColumnName = columnName;
}
}
}
Il peut alors être appelé comme ceci:
MyTable.ConvertColumnType("MyColumnName", typeof(int));
Bien sûr, en utilisant le type que vous désirez, tant que chaque valeur de la colonne peut réellement être convertie en nouveau type.
Pensez également à modifier le type de retour:
select cast(columnName as int) columnName from table
Dim tblReady1 As DataTable = tblReady.Clone()
'' convert all the columns type to String
For Each col As DataColumn In tblReady1.Columns
col.DataType = GetType(String)
Next
tblReady1.Load(tblReady.CreateDataReader)
J'ai adopté une approche un peu différente. J'avais besoin d'analyser un datetime à partir d'une importation excel au format de date OA. Cette méthodologie est assez simple pour construire à partir de... en substance,
- Ajouter une colonne du type que vous voulez
- parcourir les lignes en convertissant la valeur
-
Supprimez la colonne d'origine et renommez la nouvelle pour correspondre à l'ancienne
private void ChangeColumnType(System.Data.DataTable dt, string p, Type type){ dt.Columns.Add(p + "_new", type); foreach (System.Data.DataRow dr in dt.Rows) { // Will need switch Case for others if Date is not the only one. dr[p + "_new"] =DateTime.FromOADate(double.Parse(dr[p].ToString())); // dr[p].ToString(); } dt.Columns.Remove(p); dt.Columns[p + "_new"].ColumnName = p; }
Une fois qu'un DataTable
a été rempli, vous ne pouvez pas changer le type d'une colonne.
Votre meilleure option dans ce scénario est d'ajouter une colonne Int32
au DataTable
avant de le remplir:
dataTable = new DataTable("Contact");
dataColumn = new DataColumn("Id");
dataColumn.DataType = typeof(Int32);
dataTable.Columns.Add(dataColumn);
Ensuite, vous pouvez cloner les données de votre table d'origine vers la nouvelle table:
DataTable dataTableClone = dataTable.Clone();
Voici un message avec plus de détails .
Si vous voulez changer seulement une colonne.par exemple, de string à int32, vous pouvez utiliser expression.
DataColumn col = new DataColumn("col_int" , typeof(int));
table.columns.Add(col)
col.Expression = "table_exist_col_string"; // digit string convert to int
J'ai créé une fonction d'extension qui permet de changer le type de colonne D'un DataTable. Au lieu de cloner la table entière et d'importer toutes les données, il clone simplement la colonne, analyse la valeur, puis supprime l'original.
/// <summary>
/// Changes the datatype of a column. More specifically it creates a new one and transfers the data to it
/// </summary>
/// <param name="column">The source column</param>
/// <param name="type">The target type</param>
/// <param name="parser">A lambda function for converting the value</param>
public static void ChangeType(this DataColumn column, Type type, Func<object, object> parser)
{
//no table? just switch the type
if (column.Table == null)
{
column.DataType = type;
return;
}
//clone our table
DataTable clonedtable = column.Table.Clone();
//get our cloned column
DataColumn clonedcolumn = clonedtable.Columns[column.ColumnName];
//remove from our cloned table
clonedtable.Columns.Remove(clonedcolumn);
//change the data type
clonedcolumn.DataType = type;
//change our name
clonedcolumn.ColumnName = Guid.NewGuid().ToString();
//add our cloned column
column.Table.Columns.Add(clonedcolumn);
//interpret our rows
foreach (DataRow drRow in column.Table.Rows)
{
drRow[clonedcolumn] = parser(drRow[column]);
}
//remove our original column
column.Table.Columns.Remove(column);
//change our name
clonedcolumn.ColumnName = column.ColumnName;
}
}
Vous pouvez l'utiliser comme ceci:
List<DataColumn> lsColumns = dtData.Columns
.Cast<DataColumn>()
.Where(i => i.DataType == typeof(decimal))
.ToList()
//loop through each of our decimal columns
foreach(DataColumn column in lsColumns)
{
//change to double
column.ChangeType(typeof(double),(value) =>
{
double output = 0;
double.TryParse(value.ToString(), out output);
return output;
});
}
Le code ci-dessus change toutes les colonnes décimales en doubles.
DataTable DT = ...
// Rename column to OLD:
DT.Columns["ID"].ColumnName = "ID_OLD";
// Add column with new type:
DT.Columns.Add( "ID", typeof(int) );
// copy data from old column to new column with new type:
foreach( DataRow DR in DT.Rows )
{ DR["ID"] = Convert.ToInt32( DR["ID_OLD"] ); }
// remove "OLD" column
DT.Columns.Remove( "ID_OLD" );