2016-02-05 18 views
8

Trong mã của tôi, tôi đã sử dụng System.Data.OracleClient để kết nối cơ sở dữ liệu ora. Tôi muốn thay thế thư viện này (vì nó đã lỗi thời) với Oracle.DataAccess. Thật không may tôi thấy rằng DataRow.Field() ném InvalidCastException. Hành vi tương tự là với (decimal)x.Rows[0]["COLUME_NAME"]. Tôi không gặp vấn đề này với System.Data.OracleClient.Oracle.DataAccess DataRow.Field <decimal> InvalidCastException

Dưới đây là ví dụ mã

using (var oracleConnection = new OracleConnection(connectionString)) 
{ 
    using (var command = new OracleCommand("select * from tr", oracleConnection)) 
    { 
     var result = new DataTable(); 
     var adapter = new OracleDataAdapter(command); 
     adapter.Fill(result); 
     Console.WriteLine(result.Rows[0].Field<decimal>("TR_SEQ_NUM")); 
     //Console.WriteLine((decimal)result.Rows[0]["TR_SEQ_NUM"]); 
    } 
} 

TR_SEQ_NUM có NUMBER(8,0) datatype và đầy đủ hợp ngoại lệ là:

System.InvalidCastException: Specified cast is not valid. 
    at System.Data.DataRowExtensions.UnboxT`1.ValueField(Object value) 

Mã ví dụ làm việc với System.Data.OracleClient nhưng không phải với Oracle.DataAccess

tôi biết rằng tôi có thể sử dụng Convert.ChangeType nhưng tôi tự hỏi nếu có một số cách để có hành vi tương tự như với System.Data.OracleClient. Việc tái cấu trúc tất cả mã của tôi sẽ tốn quá nhiều thời gian.

+0

sử dụng Oracle.ManagedDataAccess.Client; // sử dụng phiên bản được quản lý Điều gì sẽ xảy ra khi bạn gọi tbl.Rows [0] [0] .GetType(); ? .Field không có khả năng trong phiên bản mới, bạn sử dụng chỉ mục/tên cột. Bạn sẽ phải refactor, System.Data.OracleClient là cách hết hạn nhưng đúc nên được xử lý cho bạn khi bạn điền vào bảng ... – Matt

+0

Ngoài ra, số (8,0) sẽ không phải là một số thập phân, tại sao bạn có đúc nó không? Rất hiếm khi Decimal cần được sử dụng, không phải là nó sẽ gây ra vấn đề bạn đang gặp phải nhưng điều đó có thể giúp bạn tiết kiệm một số bộ nhớ khi ứng dụng đang chạy – Matt

+0

Tôi đồng ý với _LessNoviceProgrammer_. Tôi nghĩ rằng loại chính xác cho 'NUMBER (8,0)' là 'int' ... –

Trả lời

1

Giá trị trong cơ sở dữ liệu không phải là số thập phân và giá trị int (tham số 'giá trị' trong thông báo lỗi) không thể truyền sang thập phân, mặc dù truyền int sang thập phân là OK. This answer leads to more info.

Bạn có thể nhìn thấy nó trong hành động với điều này:

void Main() 
{ 
    int anInt = 5; 
    object boxedInt = (object)anInt; 
    decimal unboxed = Convert.ToDecimal(boxedInt); //5 
    decimal unboxed2 = (decimal)boxedInt; //InvalidCastException 
} 

Nếu bạn nhìn vào các phương pháp Unbox.ValueField, nó ...

private static T ValueField(object value) 
    { 
    if (DBNull.Value == value) 
     throw DataSetUtil.InvalidCast(Strings.DataSetLinq_NonNullableCast((object) typeof (T).ToString())); 
    return (T) value; 
    } 

Về cơ bản bạn sẽ cần phải

Convert.ToDecimal(rows[0]["TR_SEQ_NUM"]); 
0

Có vẻ dữ liệu của bạn chứa giá trị null và bạn không thể chuyển đổi dữ liệu có thể rỗng thành loại thập phân không thể loại trừ

Vui lòng sử dụng các Statment bên dưới để đọc cột thập phân nullable từ DB

result.Rows[0].Field<decimal?>("TR_SEQ_NUM") 
Các vấn đề liên quan