如何更改DataTable中DataColumn的DataType?

我有:

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]; 

我想要做的是:

假设当前column.DataType.Name“双” 我希望它成为“Int32”

我如何做到这一点?

谢谢你的回应,如果有的话。

Datatable填充数据后,您无法更改DataType。 但是,您可以克隆数据表,更改列types并将数据从以前的数据表加载到克隆的表中,如下所示。

 DataTable dtCloned = dt.Clone(); dtCloned.Columns[0].DataType = typeof(Int32); foreach (DataRow row in dt.Rows) { dtCloned.ImportRow(row); } 

虽然确实无法在DataTable填充后更改列的types,但可以在调用FillSchema ,但在调用Fill之前对其进行更改。 例如,假设第三列是你想从double转换到Int32 ,你可以使用:

 adapter.FillSchema(table, SchemaType.Source); table.Columns[2].DataType = typeof (Int32); adapter.Fill(table); 

考虑改变返回types:

 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) 

我采取了一些不同的方法。 我需要从OAdate格式的Excel导入parsingdate时间。 这种方法很简单,可以从…构build,

  1. 添加你想要的types的列
  2. 翻阅转换值的行
  3. 删除原始列并重新命名为新的以匹配旧的

     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; } 

DataTable填充完成后,不能更改列的types。

在这种情况下,您最好的select是在填充之前将一个Int32列添加到DataTable

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

然后,可以将原始表中的数据克隆到新表中:

 DataTable dataTableClone = dataTable.Clone(); 

这里有一个更详细的信息 。

如果你想只改变一个列。例如从string到int32,你可以使用expression式。

 DataColumn col = new DataColumn("col_int" , typeof(int)); table.columns.Add(col) col.Expression = "table_exist_col_string"; // digit string convert to int 

旧的post,但我想我会用一个可以一次转换一个列的DataTable扩展名来称为给定types:

 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; } } } 

它可以被这样调用:

 MyTable.ConvertColumnType("MyColumnName", typeof(int)); 

当然可以使用任何你想要的types,只要列中的每个值都可以实际转换为新types。

我创build了一个扩展函数,它允许更改DataTable的列types。 而不是克隆整个表并导入所有的数据,只是克隆列,parsing值,然后删除原来的。

  /// <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; } } 

你可以这样使用它:

 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; }); } 

上面的代码将所有的十进制列更改为双打。

 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" ); 
Interesting Posts