2012-03-16 35 views
12

Chúng tôi có một số mã lưu trữ dữ liệu từ cơ sở dữ liệu Microsoft Access vào cơ sở dữ liệu MS SQL Server. Giả sử chúng ta có một trình đọc dữ liệu đã được điền từ bảng Access và chúng ta đang thêm một tham số vào một SqlCommand để chuẩn bị cho việc chèn, chúng ta có một kiểu dữ liệu bị lỗi. Đây là mã:Tại sao điều này diễn ra từ ngắn đến int không thành công?

oSqlServerDbCmd_ForInsert.Parameters.AddWithValue("@Duration", 
    (int) oReader["Duration"]); 

Các trường từ oReader thực sự là một truy cập Integer, đó là một đoạn ngắn trong C#. Nếu chúng ta bỏ một đoạn ngắn ở đây thì không có vấn đề gì cả. Tuy nhiên, nếu chúng ta cast vào một int thì nó sẽ ném một InvalidCastException. Tôi có thể đang hiểu sai thông tin này từ số MSDN documentation:

"Có một chuyển đổi ngầm định được xác định trước từ ngắn thành int, long, float, double hoặc thập phân."

... nhưng có vẻ như điều này sẽ hoạt động (lý do của tôi là, nếu chuyển đổi tiềm ẩn được xác định tại sao một kiểu nhập rõ ràng không hoạt động?). Tôi nhận ra rằng diễn viên thậm chí không cần thiết vì AddWithValue chấp nhận một đối tượng, vì vậy chúng tôi đã thực sự loại bỏ đoạn phim khỏi mã của chúng tôi, nhưng tôi rất muốn xem giải thích tại sao diễn viên này không thành công trong trường hợp chúng tôi gặp phải vấn đề như thế này tương lai.

+1

tốt bài báo từ Eric Lippert về vấn đề này http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

+0

Đây không phải là một câu trả lời cho bạn câu hỏi, nhưng có vẻ như tham số '@ Duration' của bạn nên có kiểu dữ liệu số, trong trường hợp này bạn không muốn sử dụng giá trị chuỗi trong lệnh 'AddWithValue'. – phoog

+0

@phoog Tôi đã chỉnh sửa mã để xóa chuyển đổi đó vì nó là sự phân tâm với câu hỏi này thực sự đã kết thúc. Câu trả lời ngắn gọn là chuyển đổi chuỗi nằm trong mã khi chúng ta thừa hưởng nó. Vì nó đã hoạt động cho đến khi chúng tôi thay đổi kiểu dữ liệu trong DB nguồn, chúng tôi không có nguyên nhân để điều tra mã. Một khi nó đã bị hỏng và chúng tôi đào trong chúng tôi thấy rằng việc chuyển đổi chuỗi là không cần thiết (mặc dù không có vấn đề, tin hay không). –

Trả lời

18

Những gì bạn có trong tay là một ví dụ của unboxing. Cụ thể khi unboxing, bạn chỉ có thể unbox thành loại giá trị ban đầu được đóng hộp; nếu loại đó là A và bạn đang unboxing thành B, thì việc chuyển đổi ngầm từ A sang B có tồn tại không (tính năng unboxing sẽ không thành công).

Xem Eric Lippert's classic blog post về chủ đề này để có giải thích liên quan.

+0

+1 Tôi luôn quên điều đó. 'đối tượng o = (ngắn) 10; int i = (int) o; 'không thành công. –

+1

Ah có ý nghĩa. Vì vậy, tôi đã lần đầu tiên đúc nó như là một đoạn ngắn sau đó tôi có thể đúc nó như là một int không có vấn đề? –

+1

@ awilson53: Chính xác. – Jon

5

Bạn cần phải biến đổi thành kiểu rất cụ thể vì bạn đang unboxing - vấn đề là oReader["Duration"] trả về một object dụ:

short myShort = 42; 
object o = myShort; 
int myInt = (int)o; //fails 

Nó sẽ thành công nếu bạn cast lại ngắn đầu tiên, sau đó đến int:

(int) (short) oReader["Duration"] 
+0

Cảm ơn phản hồi, +1 ... cả hai bạn đã trả lời câu hỏi của tôi vì vậy tôi sẽ phải đi với người đầu tiên. –

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