2012-01-27 28 views
82

que tengo:Cómo cambiar el tipo de datos de una columna de datos en una tabla de datos?

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

Lo que quiero hacer es:

Supongamos Actualmente column.DataType.Name es "doble". Quiero que se convierta en "Int32".

¿Cómo logro esto?

Gracias por su respuesta, en su caso.

Respuesta

211

No puede cambiar el tipo de datos después de que la tabla de datos esté llena de datos. Sin embargo, puede clonar la tabla de Datos, cambiar el tipo de columna y cargar los datos de la tabla de datos anterior a la tabla clonada como se muestra a continuación.

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

Gracias hermano, ayúdame aquí. Te debo una :). – rofans91

+0

me alegro de poder ayudar :) – Akhil

+0

Esto me ayudó a trabajar en una información importante. Gracias. :) – AceMark

4

Una vez que se ha rellenado DataTable, no puede cambiar el tipo de una columna.

Su mejor opción en este escenario es añadir una columna Int32 a la DataTable antes de llenarlo:

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

A continuación, se puede clonar los datos de la tabla original a la nueva tabla:

DataTable dataTableClone = dataTable.Clone(); 

Aquí hay un post with more details.

22

Si bien es cierto que no se puede cambiar el tipo de la columna después de la DataTable se llena, se puede cambiar después de llamar FillSchema, pero antes de llamar Fill. Por ejemplo, dicen que la tercera columna es la que desea convertir de double a Int32, se puede utilizar:

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

Tenga en cuenta que esto no parece funcionar si el comando de su adaptador es un procedimiento almacenado –

7

Considera también alterar el tipo de retorno:

select cast(columnName as int) columnName from table 
7
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) 
3

si quieres para cambiar solo una columna. Por ejemplo, de string a int32 puede usar expression.

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

He adoptado un enfoque diferente. Necesitaba analizar una fecha y hora de una importación de Excel que tenía el formato de fecha OA. Esta metodología es lo suficientemente simple como para construir desde ...en esencia,

  1. Añadir columna del tipo que desee
  2. extraer a través de las filas convertir el valor
  3. eliminar la columna original y cambiar el nombre de la nueva para que coincida con la edad

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

Creé una función de extensión que permite cambiar el tipo de columna de una DataTable. En lugar de clonar toda la tabla e importar todos los datos, simplemente clona la columna, analiza el valor y luego elimina el 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; 
    } 
} 

Se puede utilizar de este modo:

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

El código anterior cambia todas las columnas decimales a dobles.

0
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"); 
5

Viejo poste, pero pensé que pesaría en, con una extensión de DataTable que puede convertir una sola columna a la vez, a un tipo determinado:

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

A continuación, puede ser llama así:

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

por supuesto, el uso de cualquier tipo que desee, siempre y cuando cada valor de la columna en realidad se puede convertir en el nuevo tipo.

Cuestiones relacionadas