2012-01-27 30 views
82

tôi có:Làm thế nào để thay đổi DataType của một DataColumn trong một 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]; 

Những gì tôi muốn làm là:

Giả sử hiện column.DataType.Name"đúp". Tôi muốn nó trở thành "Int32".

Làm cách nào để đạt được điều này?

Cảm ơn bạn đã trả lời nếu có.

Trả lời

211

Bạn không thể thay đổi Kiểu dữ liệu sau khi dữ liệu có thể lưu được điền dữ liệu. Tuy nhiên, bạn có thể sao chép bảng dữ liệu, thay đổi kiểu cột và tải dữ liệu từ bảng dữ liệu trước đó vào bảng nhân bản như được hiển thị bên dưới.

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

Cảm ơn bro bạn giúp tôi ở đây. Tôi nợ bạn một :). – rofans91

+0

vui vì tôi có thể giúp :) – Akhil

+0

Điều này đã giúp tôi làm việc trên một dữ liệu quan trọng. Cảm ơn. :) – AceMark

4

Khi đã điền xong DataTable, bạn không thể thay đổi loại cột.

lựa chọn tốt nhất của bạn trong trường hợp này là thêm một cột Int32 đến DataTable trước khi điền nó:

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

Sau đó, bạn có thể sao chép dữ liệu từ bảng ban đầu của bạn vào bảng mới:

DataTable dataTableClone = dataTable.Clone(); 

Đây là số post with more details.

22

Trong khi đó là sự thật rằng bạn không thể thay đổi kiểu của cột sau DataTable được lấp đầy, bạn có thể thay đổi nó sau khi bạn gọi FillSchema, nhưng trước khi bạn gọi Fill. Ví dụ, giả sử cột thứ 3 là một trong những bạn muốn chuyển đổi double-Int32, bạn có thể sử dụng:

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

Lưu ý rằng điều này dường như không hoạt động nếu lệnh của bộ điều hợp của bạn là một thủ tục lưu sẵn –

7

cũng xem xét thay đổi kiểu trả về:

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

nếu bạn muốn để thay đổi chỉ một cột. Ví dụ từ chuỗi thành int32 bạn có thể sử dụng biểu thức.

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

Tôi đã thực hiện một cách tiếp cận khác. Tôi cần phân tích ngày giờ từ một lần nhập excel có định dạng ngày OA. Phương pháp này đủ đơn giản để xây dựng từ ...Về bản chất,

  1. Thêm cột kiểu bạn muốn
  2. Rip qua các hàng chuyển đổi giá trị
  3. Xóa cột gốc và đổi tên vào mới để phù hợp với tuổi

    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

Tôi đã tạo một chức năng mở rộng cho phép thay đổi kiểu cột của một DataTable. Thay vì nhân bản toàn bộ bảng và nhập tất cả dữ liệu, nó chỉ nhân bản cột, phân tích giá trị và sau đó xóa bản gốc.

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

Bạn có thể sử dụng nó như vậy:

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

Đoạn mã trên thay đổi tất cả các cột thập phân để đánh đôi.

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

Cũ bưu điện, nhưng tôi nghĩ rằng tôi muốn cân nhắc trong, có phần mở rộng DataTable mà có thể chuyển đổi một cột duy nhất tại một thời điểm, một loại nhất định:

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

Sau đó nó có thể được gọi là như thế này:

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

Tất nhiên sử dụng bất kỳ loại nào bạn mong muốn, miễn là mỗi giá trị trong cột có thể thực sự được chuyển đổi thành loại mới.

Các vấn đề liên quan