2012-09-07 58 views
5

讀取的數據7200000有錯誤
Invalid Cast Exception.通用方法我目前使用此方法來讀取從DataReader的數據從DataReader的

我在考慮修改我的方法來替換 -

return (T)obj; 

return (T)Convert.ChangeType(obj, typeof(T)); 

但期待着爲這一改變更好的辦法將涉及型鑄造兩次。
有什麼更好的想法?

謝謝!

+0

什麼數據類型是columnName3數據庫? – RQDQ

+0

你見過Linq to Dataset嗎? –

+0

@RQDQ,它是SQL Server數據類型'real'。我只是嘗試在控制檯應用程序中使用以下代碼進行復制:object objValue = 7200000; float floatValue =(float)objValue; //這裏失敗 – iniki

回答

4

一個通用的方法的優點是可以減少大量的代碼膨脹,但否則爲每個數據類型生成自己的包裝可以讓您靈活地進行自定義處理。而且很可能你的db查詢會比檢索模式對性能有明顯的影響。

我建議你編寫一套你自己的擴展方法,而不是使用一種通用方法。在IDataReader上擴展方法爲您提供了不傳播整個對象子類型的方法的好處。我不得不單獨處理類型,因爲各種連接器的行爲不同,尤其是Guid類型。如果數據讀取器在兩種情況下都返回0DBNull,則很難知道它是否爲0。比方說,你的表中有一個null值的枚舉字段。爲什麼你會希望它被看作是第一個枚舉?

只要致電:

dataReader.GetInt("columnName1") 
dataReader.GetString("columnName3") 
dataReader.GetFloat("columnName3") 

而且方法:

public static int? GetInt(this IDataReader r, string columnName) 
{ 
    var i = r[columnName];  
    if (i.IsNull()) 
     return null; //or your preferred value 

    return (int)i; 
} 

public static bool IsNull<T>(this T obj) where T : class 
{ 
    return (object)obj == null || obj == DBNull.Value; 
} 

同樣,

public static string GetString(this IDataReader r, string columnName) 
{ 
} 

public static float GetFloat(this IDataReader r, string columnName) 
{ 
} 

如果你真的想要一個通用的功能,你可以擁有它了。

public static T Get<T>(this IDataReader r, string columnName, T defaultValue = default(T)) 
{ 
    var obj = r[columnName];  
    if (obj.IsNull()) 
     return defaultValue; 

    return (T)obj; 
} 

所以稱它爲

dataReader.Get<int>(1); //if DBNull should be treated as 0 
dataReader.Get<int?>(1); //if DBNull should be treated as null 
dataReader.Get<int>(1, -1); //if DBNull should be treated as a custom value, say -1 

也就是說,錯誤是因爲你沒有右型鑄造在評論中指出。我本可以用內置的DBNull檢查,但我不避免數據從閱讀器被多次讀取,inspired from this curious case of microoptimization

0

從.NET Framework 4開始。5

static class SqlReaderExtension 
{ 
    public static async Task<T> ReadAsync<T>(this SqlDataReader reader, string fieldName) 
    { 
     if (reader == null) throw new ArgumentNullException(nameof(reader)); 
     if (string.IsNullOrEmpty(fieldName)) 
      throw new ArgumentException("Value cannot be null or empty.", nameof(fieldName)); 

     int idx = reader.GetOrdinal(fieldName); 
     return await reader.GetFieldValueAsync<T>(idx); 
    } 
} 

然後

string result = await reader.ReadAsync<string>("FieldName");