2016-02-05 11 views
8

W moim kodzie użyłem System.Data.OracleClient dla połączenia z bazą danych ora. Chciałbym zastąpić tę bibliotekę (ponieważ jest przestarzała) z Oracle.DataAccess. Niestety znalazłem, że DataRow.Field() rzuca InvalidCastException. To samo zachowanie jest z (decimal)x.Rows[0]["COLUME_NAME"]. Nie mam tego problemu z System.Data.OracleClient.Oracle.DataAccess DataRow.Field <decimal> InvalidCastException

Oto przykład kodu

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 ma NUMBER(8,0) typ danych i pełne Wyjątkiem jest:

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

przykład Kodeks pracy z System.Data.OracleClient ale nie z Oracle.DataAccess

wiem, że mogę używać Convert.ChangeType ale zastanawiam się, czy istnieje sposób, aby zachować takie samo zachowanie, jak w przypadku System.Data.OracleClient. Refaktoryzacja całego mojego kodu będzie zbyt długa.

+0

wykorzystaniem Oracle.ManagedDataAccess.Client; // użyj zarządzanej wersji Co się dzieje, gdy wywołasz tbl.Rows [0] [0] .GetType(); ? .Field nie jest możliwy w nowej wersji używasz indeksów kolumn/nazw. Będziesz musiał naprawić, System.Data.OracleClient jest nieaktualny, ale odlewanie powinno być obsłużone dla ciebie, gdy wypełnisz tabelę ... – Matt

+0

Również liczba (8,0) nie będzie dziesiętna, dlaczego podrzucasz go do jednego? Bardzo rzadko zdarza się, że trzeba używać Decimal, nie że spowoduje to problem, ale może zaoszczędzić trochę pamięci, gdy aplikacja działa – Matt

+0

Zgadzam się z _LessNoviceProgrammer_. Myślę, że poprawny typ dla 'NUMBER (8,0)' to 'int' ... –

Odpowiedz

1

Wartość w bazie danych nie jest liczbą dziesiętną, a pole w int (parametr "wartość" w komunikacie o błędzie) nie może być rzutowane na wartość dziesiętną, pomimo podania wartości int do liczby dziesiętnej w porządku. This answer leads to more info.

Można zobaczyć go w akcji z tym:

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

Jeśli spojrzeć na metody Unbox.ValueField, robi ...

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

Zasadniczo trzeba

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

Wygląda na to, że dane zawierają wartość NULL i nie można przekonwertować danych zerowych na nieopróżnialny typ dziesiętny

Proszę użyć poniższego statment przeczytać zerowalne kolumny dziesiętnej z DB

result.Rows[0].Field<decimal?>("TR_SEQ_NUM") 
Powiązane problemy