2010-03-29 45 views
11

Tôi có một System.Data.DataTable được điền bằng cách đọc tệp CSV đặt bộ dữ liệu của từng cột thành chuỗi.Thay đổi kiểu dữ liệu cột DataTable được điền sẵn

Tôi muốn nối thêm nội dung của DataTable vào bảng cơ sở dữ liệu hiện có - hiện tại việc này được thực hiện bằng cách sử dụng SqlBulkCopy với DataTable làm nguồn.

Tuy nhiên, các kiểu dữ liệu cột của DataTable cần phải được thay đổi để phù hợp với giản đồ của bảng cơ sở dữ liệu đích, xử lý giá trị null.

Tôi không quen thuộc với ADO.NET vì vậy đã tìm kiếm một cách làm sạch?

Cảm ơn.

Trả lời

10

Bạn không thể thay đổi DataType của một DataColumn sau Populating nó với dữ liệu. Nó không phải là một thuộc tính chỉ đọc, nhưng bạn sẽ nhận được một ngoại lệ khi chạy nếu bạn cố gắng thay đổi nó sau khi nó đã có dữ liệu.

Từ documentation:

Một ngoại lệ được tạo ra khi thay đổi thuộc tính này sau khi cột đã bắt đầu lưu trữ dữ liệu.

Vì vậy, bạn sẽ phải hoặc là đảm bảo các loại cột chính xác ngay từ đầu (nếu có thể), hoặc tạo mới DataTable đặc biệt cho việc nhập khẩu và sao chép dữ liệu từ bản gốc DataTable.

Bạn cũng có thể viết lớp tùy chỉnh IDataReader đọc từ số DataTable và thực hiện chuyển đổi ngay trong thời gian và chuyển cho SqlBulkCopy - nó sẽ hiệu quả hơn nhiều, nhưng rõ ràng không phải là sửa chữa nhanh.

+0

Cảm ơn - Tôi nhận ra rằng tôi không thể thay đổi nó sau khi được điền. Những gì tôi đang tìm kiếm là một cách để tạo ra một DataTable thứ hai với các kiểu dữ liệu chính xác và sau đó nhập và chuyển đổi dữ liệu từ DataTable đầu tiên. Nó không thể cho DataTable đầu tiên sử dụng các kiểu dữ liệu khác ngoài String không may. – TonE

+0

@TonE: Cách duy nhất tôi có thể nghĩ để làm điều đó là triển khai 'IDataReader' và sử dụng phương thức' DataTable.Load' - nhưng nếu bạn định làm điều đó, bạn cũng có thể sử dụng chính trình đọc cho 'SqlBulkCopy' thay vì tạo' DataTable' thứ hai. – Aaronaught

+0

Đó là một gợi ý thú vị. Liệu nó có thể lấy được từ DataTableReader hay không và liệu bạn có biết cách nào tôi cần phải ghi đè để cung cấp chức năng thay đổi kiểu không? Chỉ cần cố gắng để đánh giá nếu nó là chính đáng cho các ràng buộc thời gian. – TonE

3

Đảm bảo đặt các kiểu dữ liệu của dữ liệu bạn đang điền.

ví dụ .:

DataTable table = new DataTable("countries"); 
    table.Columns.Add("country_code", typeof (string)); 
    table.Columns.Add("country_name", typeof (string)); 
    //... 
    //Fill table 

Hoặc bạn có thể thay đổi các loại cột nếu họ là tương thích:

table.Columns["country_code"].DataType = typeof(string); 
+0

Vâng, đây là những gì tôi hiện đang thực hiện nhưng thực sự điền DataTable thứ hai với các loại được đặt chính xác đang chứng minh là khó khăn. Có một cách đơn giản để làm điều này? – TonE

9

tôi đã viết hàm tổng quát này để thực hiện công việc, nó hoạt động rất tốt đối với tôi:

public static bool ChangeColumnDataType(DataTable table, string columnname, Type newtype) 
{ 
    if (table.Columns.Contains(columnname) == false) 
     return false; 

    DataColumn column= table.Columns[columnname]; 
    if (column.DataType == newtype) 
     return true; 

    try 
    { 
     DataColumn newcolumn = new DataColumn("temporary", newtype); 
     table.Columns.Add(newcolumn); 
     foreach (DataRow row in table.Rows) 
     { 
      try 
      { 
       row["temporary"] = Convert.ChangeType(row[columnname], newtype); 
      } 
      catch 
      { 
      } 
     } 
     table.Columns.Remove(columnname); 
     newcolumn.ColumnName = columnname; 
    } 
    catch (Exception) 
    { 
     return false; 
    } 

    return true; 
} 

Bạn chỉ có thể sao chép mã và đặt nó trong một lớp học (MyClass đây), và sử dụng nó như thế này làm ví dụ:

MyClass.ChangeColumnDataType(table, "GEOST", typeof (int)); 
+1

Vấn đề duy nhất - cột mới được thêm vào cuối bộ sưu tập, ví dụ, nếu bạn ràng buộc nó vào lưới với "autogeneratecolumns = true" thì vị trí thứ tự sẽ khác nhau –

+1

Sửa lỗi đó :) Và sử dụng nó trong giải pháp của tôi nếu bạn không nhớ: http://codecorner.galanter.net/2013/08/02/ado-net-datatable-change-column-datatype-after-table-is-populated-with-data/ –

1

Nếu bạn đang điền từ tệp csv, sau đó đọc lược đồ đầu tiên trong dữ liệu sau đó thay đổi kiểu dữ liệu của cột rồi điền bảng. Ví dụ: Tôi đang sử dụng tệp XML để nhập dữ liệu.

 DataSet dstemp = new DataSet(); 
     dstemp.ReadXmlSchema(@"D:\path of file\filename.xml"); 
     dstemp.Tables[0].Columns["Student_id"].DataType = typeof(Guid); 
     dstemp.ReadXml(@"D:\path of file\filename.xml"); 

Tôi nghĩ nó sẽ phù hợp với bạn.

0

Cũng giống như "Eddie Monge Jr" hoặc "Gisway" không thể tải xuống.

nhưng với thứ tự cột chính xác.

public static bool ChangeColumnDataType(DataTable table, string columnname, Type newtype){ 
    if (table.Columns.Contains(columnname) == false) 
     return false; 

    DataColumn column = table.Columns[columnname]; 
    if (column.DataType == newtype) 
     return true; 

    try{ 
     DataColumn newcolumn = new DataColumn("temporary", newtype); 
     table.Columns.Add(newcolumn); 

     foreach (DataRow row in table.Rows){ 
      try{ 
       row["temporary"] = Convert.ChangeType(row[columnname], newtype); 
      } 
      catch{} 
     } 
     newcolumn.SetOrdinal(column.Ordinal); 
     table.Columns.Remove(columnname); 
     newcolumn.ColumnName = columnname; 
    } 
    catch (Exception){ 
     return false; 
    } 

    return true; 
} 
Các vấn đề liên quan