2009-09-01 68 views
5

我發現了一個解決此錯誤的解決方法,但我現在真的很好奇爲什麼會發生這種情況,想知道是否有其他人有這個錯誤。從數據讀取器解析小數

我的功能如下:

public void Blog_GetRating(int blogID, ref decimal rating, ref int voteCount) 
{ 
    // Sql statements 
    // Sql commands 

    if (DataReader.Read()) 
    { 
     // this line throws a 'Input string was not in a correct format.' error. 
     rating = decimal.Parse(DataReader["Rating"].ToString()); 

     // this works absolutly fine?! 
     decimal _rating = 0; 
     decimal.TryParse(DataReader["Rating"].ToString(), out _rating); 

     rating = _rating; 
    } 
} 

有誰看到過?

什麼是更加古怪的是,如果我輸入:

rating = decimal.Parse("4.0"); 

工作正常,在4.0什麼是從我的DataReader出來。

正如我前面所說,TryParse方法工作正常,所以它不阻止我攜帶,但現在我真的很感興趣,看看有沒有人有答案。

期待一些回覆!

肖恩

編輯 - 解決

的decimal.Parse方法做工精細,功能正在運行第二次(是在一個循環中),後沒有被評爲所以數據讀取器返回空值。在我的SQL計算中包裝COALESCE解決了這個問題。因此,正如你所說的那樣,爲什麼tryparse方法沒有拋出異常,只是將默認值0保留爲_rating。

+1

爲什麼不把列設爲數字,所以不需要解析? – 2009-09-01 15:55:25

回答

10

這對我來說根本不奇怪。

Decimal.Parse()假設爲壞格式拋出異常。 Decimal.TryParse()不會拋出該異常,而只是返回false。該踢球者是你沒有檢查從Decimal.TryParse()返回的值。我會給你很好的賠率,Decimal.TryParse()對於每個導致Decimal.Parse()的異常的輸入都返回false,並且在其他地方都是true。當Decimal.TryParse()返回false時,輸出參數總是「0」。

一個可能的警告是本地化。如果Decimal.Parse()正在抱怨看似正常的輸入,則可以檢查服務器上使用的數字格式(當前文化)是否使用逗號而不是小數來將係數與尾數分開。但考慮到你的「4.0」測試工作正常,我懷疑這是問題所在。

最後,在從數據讀取器進行此轉換時,應考慮數據讀取器的源列類型。如果可能已經是小數。爲什麼只將它轉換爲字符串才能將其轉換回來?

2

你是說這個:

// this works absolutly fine?! 
    decimal _rating = 0; 
    decimal.TryParse(DataReader["Rating"].ToString(), out _rating); 

但是你沒有實際檢查的TryParse的返回值。我猜你的TryParse實際上是失敗的(返回false),因爲decimal.Parse和decimal.TryParse使用相同的「規則」進行解析,因爲你使用的是重載。

我懷疑這兩者都沒有按照您的想法工作。兩者都可能失敗,但TryParse不會拋出。

0

您的TryParse改成這樣,然後再試一次:

if (!decimal.TryParse(DataReader["Rating"].ToString(), out _rating)) 
{ 
    throw new Exception("Input string was not in a correct format"); 
} 

我敢打賭,這也扔...

1

的SQL小數列將不解析到可以轉換爲十進制的字符串,所以tryparse將返回false。嘗試這樣的:

if (Convert.IsDBNull(reader["DecimalColumn"])) 
    { 
     decimalData = 0m; 
    } 
    else 
    { 
     decimalData = reader.GetDecimal(reader.GetOrdinal("DecimalColumn")); 
    } 
+0

謝謝,當我從加載數據集(即獲取OutOfMemory異常)切換到使用DataReader時,這很有幫助。我這樣做︰'decimalData =(Convert.IsDBNull(reader [「DecimalColumn」]))? 0:reader.GetDecimal(reader.GetOrdinal(「DecimalColumn」));' – ScottK 2013-01-30 21:11:06

1

我今天面臨同樣的問題。 試試這個:

rating = decimal.Parse("4,0"); 

它會給你同樣的錯誤。


背後的原因是文化。在法國文化中,4.0被表示爲4.0,因此它會拋出異常。

decimal.TryParse是文化不變的方法,因此它工作正常。

+0

'decimal.TryParse(「4.0」,NumberStyles.Number,CultureInfo.InvariantCulture,out rating);' – 2014-09-26 17:01:18