Как изменить тип данных DataColumn в DataTable?
Я:
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".
Как мне этого добиться?
10 ответов:
вы не можете изменить тип данных после того, как Datatable заполняется данными. Однако можно клонировать таблицу данных, изменить тип столбца и загрузить данные из предыдущей таблицы данных в клонированную таблицу, как показано ниже.
DataTable dtCloned = dt.Clone(); dtCloned.Columns[0].DataType = typeof(Int32); foreach (DataRow row in dt.Rows) { dtCloned.ImportRow(row); }
а это правда, что вы не можете изменить тип столбца после
DataTableзаполняется, вы можете изменить его после вызоваFillSchema, но прежде чем позвонитьFill. Например, скажем, 3-й столбец-это тот, который вы хотите преобразовать изdoubleдоInt32, вы могли бы использовать:adapter.FillSchema(table, SchemaType.Source); table.Columns[2].DataType = typeof (Int32); adapter.Fill(table);
старый пост, но я думал, что буду взвешивать, с расширением DataTable, которое может конвертировать один столбец за раз, в заданный тип:
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));конечно, используя любой тип, который вы хотите, пока каждое значение в столбце может быть фактически преобразовано в новый тип.
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)
Я взял немного другой подход. Мне нужно было проанализировать datetime из импорта excel, который был в формате даты OA. Данная методика является достаточно простой, чтобы построить из... в сущности,
- добавить столбец типа
- Rip через строки преобразования значения
удалите исходный столбец и переименуйте его в новый, чтобы он соответствовал старому
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было заполнено, вы не можете изменить тип столбца.ваш лучший вариант в этом случае-добавить до
DataTableпрежде чем заполнять это:dataTable = new DataTable("Contact"); dataColumn = new DataColumn("Id"); dataColumn.DataType = typeof(Int32); dataTable.Columns.Add(dataColumn);затем вы можете клонировать данные из исходной таблицы в новую таблицу:
DataTable dataTableClone = dataTable.Clone();
Если вы хотите поменять только колонки.например из String в int32 можно использовать выражение.
DataColumn col = new DataColumn("col_int" , typeof(int)); table.columns.Add(col) col.Expression = "table_exist_col_string"; // digit string convert to int
Я создал функцию расширения, которая позволяет изменять тип столбца DataTable. Вместо клонирования всей таблицы и импорта всех данных он просто клонирует столбец, анализирует значение и затем удаляет оригинал.
/// <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" );
Comments