I created an extension function that allows you to change the type of a DataTable column. Instead of cloning the entire table and importing all the data, it simply clones the column, analyzes the value, and then deletes the 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; } }
You can use it like this:
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; }); }
The code above changes all decimal columns to two.
Wes Hanney Oct 12 '16 at 10:28 2016-10-12 22:28
source share