2012-01-27 26 views
82

Ben:DataTable bir DataColumn DataType Nasıl Değiştirilir?

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

Ne yapmak istiyorum:

anda column.DataType.Name"Double" olduğunu varsayın. Bunun "Int32" olmasını istiyorum.

Bunu nasıl başarırım?

Yanıtınız için teşekkür ederiz.

cevap

211

Datatable veriyle doldurulduktan sonra DataType'ı değiştiremezsiniz. Ancak, Veri tablosunu klonlayabilir, sütun türünü değiştirebilir ve önceki veri tablosundaki verileri aşağıda gösterildiği gibi klonlanmış tabloya yükleyebilirsiniz.

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

Buraya yardım ettiğiniz için teşekkürler. Sana borçlandım :). – rofans91

+0

ben yardımcı olabilir :) – Akhil

+0

Bu önemli bir veri üzerinde çalışmama yardımcı oldu. Teşekkürler. :) – AceMark

4

DataTable bir kez doldurulduğunda, bir sütunun türünü değiştiremezsiniz.

bu senaryoda En iyi seçenek doldurmadan önce DataTable bir Int32 sütun eklemektir:

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

Sonra yeni tabloya orijinal tablodan verileri klonlayabilirsiniz:

DataTable dataTableClone = dataTable.Clone(); 

İşte bir post with more details.

22

o DataTable doldurulur sonra sütunun türünü değiştiremezsiniz doğru olmakla birlikte, size FillSchema çağırdıktan sonra bunu değiştirmek, ama önce Fill çağırabilir. Örneğin, 3 sütun Int32 için double dönüştürmek istediğiniz biridir demek, şunu kullanabilirsiniz:

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

Adaptörünüzün komutunun saklı bir prosedür olması durumunda bunun işe yaramayacağını unutmayın. –

7

da dönüş türü değiştirerek düşünün sadece bir sütun değiştirmek için. örneğin dize ile int32 arasında ifade kullanabilirsiniz.

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

isterseniz:

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

Biraz farklı bir yaklaşım attım. OA tarih biçimindeki bir excel içe aktarmasından bir tarih ayrıştırmak gerekiyordu. Bu metodoloji inşa etmek için yeterince basittir ...özünde,

  1. Eğer satırlar arasında
  2. Rip
  3. orijinal Sütunu sil ve maç için yeniye yeniden adlandırmak değeri dönüştürme istediğiniz Çeşidi sütun ekleyin eski

    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'ın sütun türünü değiştirmeye izin veren bir uzantı işlevi oluşturdum. Tüm tabloyu klonlamak ve tüm verileri içe aktarmak yerine sadece sütunu klonlar, değeri ayrıştırır ve orijinali siler.

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

Öyle gibi kullanabilirsiniz:

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

Yukarıdaki kod çiftlerde tüm ondalık sütunları değiştirir.

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

Daha sonra olabilir:

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

Eski sonrası, ama ben belirli bir türe, bir defada tek bir sütun dönüştürebilirsiniz DataTable uzantılı, tartmak düşünmüştüm böyle seslendi: ne arzu tipi kullanılarak tabii

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

sürece sütundaki her değer aslında yeni tip dönüştürülebilir olarak.