2012-01-27 9 views
82

는 내가 가진 :DataTable에서 DataColumn의 데이터 형식을 변경하는 방법?

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"이 되길 원합니다.

어떻게해야합니까?

답변 해 주셔서 감사합니다.

답변

211

데이터 테이블을 데이터로 채운 후에는 데이터 유형을 변경할 수 없습니다. 그러나 데이터 테이블을 복제하고 열 유형을 변경하고 데이터를 이전 데이터 테이블에서 복제 된 테이블로로드 할 수 있습니다 (아래 그림 참조).

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

감사합니다. 당신이 나를 도와주세요. 내가 당신 께 신세를지는 거죠 :). – rofans91

+0

기꺼이 도와 드리겠습니다. – Akhil

+0

이것은 중요한 데이터 작업에 도움이되었습니다. 감사. :) – AceMark

4

DataTable이 채워지면 열 유형을 변경할 수 없습니다.

이 시나리오에있는 당신의 최선의 선택을 작성하기 전에 DataTableInt32 열을 추가하는 것입니다

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

그런 다음 새 테이블에 원본 테이블의 데이터를 복제 할 수 있습니다

DataTable dataTableClone = dataTable.Clone(); 

여기에 post with more details이 있습니다.

22

DataTable가 작성 후 당신이 컬럼의 유형을 변경할 수 없습니다 것은 사실이지만, 당신이 FillSchema를 호출 한 후 변경,하지만 전에 Fill를 호출 할 수 있습니다. 예를 들어, 3 열은 Int32double에서 변환 할 하나라고, 당신은 사용할 수 있습니다

select cast(columnName as int) columnName from table 
+1

어댑터의 명령이 저장 프로 시저 인 경우이 방법이 작동하지 않습니다. –

7

는 반환 형식을 변경하는 것을 고려 예를 들어 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 
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

원하는 경우 :

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

나는 다른 접근 방식을 사용했습니다. OA 날짜 형식의 Excel 가져 오기에서 datetime을 구문 분석해야했습니다. 이 방법론은 충분히 간단합니다.본질적으로,

  1. 은 행을 통해
  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; 
        } 
    
1

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

위의 코드는 두 배에 모든 소수 열을 변경합니다.

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

것은 그런 다음 될 수 있습니다

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

올드 게시,하지만 난 주어진 형식으로, 한 번에 하나의 열을 변환 할 수있는 DataTable을 확장자에 무게 줄 알았는데

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

물론 열의 각 값을 실제로 새 유형으로 변환 할 수있는 한 원하는 유형을 사용하십시오.

관련 문제