2012-03-16 29 views
12

Verileri bir Microsoft Access veritabanından MS SQL Server veritabanına arşivleyen bazı kodlarımız var. Access tablosundan daha önceden doldurulmuş bir veri okuyucumuz olduğunu varsayalım ve insert için hazırlık olarak SqlCommand'a bir parametre ekliyoruz, başarısız olan bir yazımımız var. oReader danNiçin bu kısa zamanda int başarısız olur?

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

alan aslında C# kısa bir Access Tamsayı şöyledir: Burada kodudur. Eğer kısa bir kısma gidersek sorun olmaz. Bununla birlikte, eğer bir int için koyarsak, InvalidCastException atar. Bu hatayı, MSDN documentation:

"Yanlış, uzun, süzülme, çift veya ondalıktan önceden tanımlanmış örtük bir dönüşüm var."

... ama bu işe yarayacak gibi geliyor (mantıksal bir dönüşüm tanımlanırsa neden açık bir yazım neden işe yaramaz?). AddWithValue bir nesneyi kabul ettiği için oyuncu kadrosunun gerekli olmadığının farkındayım, bu yüzden oyuncu kadromuzu kodumuzdan kaldırdık, ancak böyle bir şeye rastladığımızda, bu dökümün neden başarısız olduğuyla ilgili bir açıklama görmeyi çok isterim. gelecek.

+1

İyi makale bu http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

+0

Bu bir cevap değil senin soru, ama '@ Duration' parametrenizin bir sayısal veri türü, bu durumda 'AddWithValue' çağrısında dize değeri kullanmak istemezsiniz. – phoog

+0

@phoog Bu dönüştürmeyi kaldırmak için kodu değiştirdim, çünkü bu sorunun gerçekten bittiği noktadan saptı. Kısa cevap, dize dönüşümünün miras aldığımız zaman kodda olmasıydı. Kaynak DB'deki veri türünü değiştirene kadar çalıştığı için kodu araştırmak için hiçbir nedenimiz yoktu. Bir kez kırıldı ve biz kazdık dize dönüşüm gereksiz olduğunu gördük (sorunlu olmasa da, inanın ya da değil). –

cevap

18

Elinizde ne var, unboxing'un bir örneğidir. Özellikle kutudan çıkarıldığında, orijinal olarak kutsanan değerin türüne yalnızca kutudan çıkartabilirsiniz; Bu tür bir A ise ve B, için kutusundan ayrılıyorsanız, A'dan B'ye bir örtük dönüştürme (kutudan çıkarılma hala başarısız olur) fark etmez. Konuyla ilgili açıklama için konu hakkındaki Eric Lippert'in classic blog post konusuna bakın. Eğer unboxing beri

+0

+1 Her zaman bunu unutuyorum. 'nesne o = (kısa) 10; int i = (int) o; 'başarısız. –

+1

Ah bu mantıklı. Öyleyse, ilk önce onu kısa bir süre olarak yayınlayabildim, o zaman bunu bir sorun olmadan bir int olarak yapabilirdim? –

+1

@ awilson53: Tam olarak. – Jon

5

Çok spesifik tür atama zorunda - Sorun oReader["Duration"] bir object örneğini döndürür olmasıdır:

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

Size daha sonra int, kısa birinci geri döküm eğer başarılı olacaktır:

(int) (short) oReader["Duration"] 
Eric Lippert dan
+0

Geri bildiriminiz için teşekkürler, +1 ... siz ikiniz de sorumu cevapladınız, bu yüzden ilk harekete geçmem gerekecek. –

İlgili konular