Comment changer le DataType d’un 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 c’est:

Supposons que column.DataType.Name est actuellement “Double” . Je veux qu’il devienne “Int32” .

Comment puis-je y arriver?

Vous ne pouvez pas modifier le DataType une fois que le Datatable est rempli avec des données. Toutefois, vous pouvez cloner le tableau Données, modifier le type de colonne et charger les données du tableau de données précédent dans le tableau cloné, 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 modifier le type de la colonne après le remplissage du DataTable , vous pouvez le modifier 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); 

Envisagez également de 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 Ssortingng For Each col As DataColumn In tblReady1.Columns col.DataType = GetType(Ssortingng) Next tblReady1.Load(tblReady.CreateDataReader) 

Ancien message, mais je pensais que je devais 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, ssortingng 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; } } } 

On peut alors l’appeler 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 être convertie dans le nouveau type.

J’ai adopté une approche différente. J’avais besoin d’parsingr une date / heure à partir d’une importation Excel au format de date OA. Cette méthodologie est assez simple pour construire à partir de … en substance,

  1. Ajouter une colonne de type que vous voulez
  2. Extraire les lignes en convertissant la valeur
  3. Supprimer la colonne d’origine et renommer la nouvelle pour correspondre à l’ancienne

     private void ChangeColumnType(System.Data.DataTable dt, ssortingng 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].ToSsortingng())); // dr[p].ToSsortingng(); } dt.Columns.Remove(p); dt.Columns[p + "_new"].ColumnName = p; } 

Une fois un DataTable rempli, vous ne pouvez pas modifier le type d’une colonne.

Votre meilleure option dans ce scénario consiste à append une colonne Int32 au DataTable avant de la remplir:

 dataTable = new DataTable("Contact"); dataColumn = new DataColumn("Id"); dataColumn.DataType = typeof(Int32); dataTable.Columns.Add(dataColumn); 

Vous pouvez ensuite cloner les données de votre table d’origine vers la nouvelle table:

 DataTable dataTableClone = dataTable.Clone(); 

Voici un post avec plus de détails .

Si vous voulez changer uniquement une colonne.pour exemple de chaîne en int32, vous pouvez utiliser l’expression.

 DataColumn col = new DataColumn("col_int" , typeof(int)); table.columns.Add(col) col.Expression = "table_exist_col_ssortingng"; // digit ssortingng 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, elle ne fait que cloner la colonne, parsing la valeur puis supprime l’original.

  ///  /// Changes the datatype of a column. More specifically it creates a new one and transfers the data to it ///  /// The source column /// The target type /// A lambda function for converting the value public static void ChangeType(this DataColumn column, Type type, Func 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().ToSsortingng(); //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 ça:

 List lsColumns = dtData.Columns .Cast() .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.ToSsortingng(), out output); return output; }); } 

Le code ci-dessus modifie 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" );