如何更改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,
- 添加你想要的types的列
- 翻阅转换值的行
-
删除原始列并重新命名为新的以匹配旧的
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" );