从 DataReader 解析小数

发布于 2024-08-03 02:44:44 字数 992 浏览 7 评论 0原文

我找到了解决此错误的方法,但我现在真的很好奇为什么会发生这种情况,想知道是否有其他人遇到过此错误。

我的功能如下:

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 方法工作得很好,所以它并没有阻止我继续进行,但现在我真的很想看看是否有人有答案。

期待一些回复!

Sean

编辑-已解决

decimal.Parse方法工作正常,该函数第二次运行(在循环中),帖子尚未评级,因此返回空值数据读取器。在 SQL 中对我的计算进行 COALESCE 很好地解决了问题。因此,正如您所说,为什么 tryparse 方法没有抛出异常,只是将默认值 0 保留为 _ rating 。

I found a workaround for this error, but am now really curious as to why this would be happening, was wondering if anyone else has had this error.

My function is as follows:

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;
    }
}

Anyone ever seen that before?

What's even weirder is if i type this:

rating = decimal.Parse("4.0");

that works fine, the 4.0 is what is coming out from my DataReader.

As I said previous, the TryParse method works fine so it's not stopping me from carrying, but now I'm really interested to see if anyone has an answer for it.

Looking forward to some replies!

Sean

EDIT - SOLVED

The decimal.Parse method was working fine, the second time the function was running (was in a loop), a post hadn't been rated so a null value was being returned by the data reader. Wrapping COALESCE round my calculation in SQL solved the problem fine. Hence why, as you said, the tryparse method wasn't throwing an exception, just keeping the default of 0 to _rating.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

国际总奸 2024-08-10 02:44:45

我今天面临同样的问题。
试试这个:

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

它会给你同样的错误。


这背后的原因是文化。在法国文化中,4.0 表示为 4,0,因此它会抛出异常。

decimal.TryParse 是文化不变的方法,因此它可以很好地工作。

I am facing same problem today.
Try this:

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

It will give you same error.


The reason behind this is the culture. In the French culture, 4.0 is represented as 4,0, and hence it throws an Exception.

decimal.TryParse is culture invariant method and hence it works fine you.

甜尕妞 2024-08-10 02:44:45

将您的 TryParse 更改为此并重试:

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

我打赌这确实会抛出......

Change your TryParse to this and try again:

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

I bet this does throw...

七颜 2024-08-10 02:44:44

这对我来说一点也不奇怪。

Decimal.Parse() 应该针对错误格式抛出异常。 Decimal.TryParse() 不会抛出该异常,而只是返回 false。更重要的是,您没有检查 Decimal.TryParse() 的返回值。我会给您很好的机会 Decimal.TryParse() 对于导致 Decimal.Parse() 异常的每个输入返回 false,在其他地方返回 true。当 Decimal.TryParse() 返回 false 时,输出参数始终仅为“0”。

一个可能的警告是本地化。如果 Decimal.Parse() 抱怨看似正常的输入,您可以检查服务器上使用的数字格式(当前区域性)是否使用逗号而不是小数来分隔系数和尾数。但考虑到你的“4.0”测试运行良好,我怀疑这就是问题所在。

最后,当从数据读取器进行此转换时,您应该考虑数据读取器的源列类型。如果可能已经是小数了。为什么将其转换为字符串后才将其转换回来?

That doesn't look weird to me at all.

Decimal.Parse() is supposed to throw an exception for bad formats. Decimal.TryParse() will not throw that exception, but instead just return false. The kicker is that you're not checking the return value from Decimal.TryParse(). I'll give you real good odds that Decimal.TryParse() returns false for every input that causes an exception with Decimal.Parse(), and true everywhere else. And when Decimal.TryParse() returns false, the output argument is always just "0".

The one possible caveat is localization. If Decimal.Parse() is complaining about a seemingly normal input, you might check if the number format (current culture) used on your server uses a comma rather than a decimal to separate the coefficient from the mantissa. But given your "4.0" test worked fine, I doubt this is the problem.

Finally, when doing this conversion from data reader you should consider the source column type of the data reader. If might already be a decimal. Why convert it to a string only to convert it back?

晨曦慕雪 2024-08-10 02:44:44

你是这样说的:

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

但你实际上并没有检查 TryParse 的返回值。我猜你的 TryParse 实际上失败了(返回 false),因为在给定你正在使用的重载的情况下,decimal.Parse 和decimal.TryParse 使用相同的“规则”进行解析。

我怀疑两者都没有像你想象的那样工作。两者都可能失败,但 TryParse 不会抛出。

You are saying this:

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

But you didn't actually check the return value of TryParse. I would guess that your TryParse is actually failing (returning false), since decimal.Parse and decimal.TryParse use the same "rules" for parsing, given the overloads you're using.

I suspect that neither is working as you think. Both are probably failing, but TryParse won't throw.

多像笑话 2024-08-10 02:44:44

sql 小数列不会解析为可以转换为小数的字符串,因此 tryparse 将返回 false。尝试这样的事情:

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

The sql decimal column won't parse to a string that can convert to a Decimal, so tryparse will return false. Try something like this:

 if (Convert.IsDBNull(reader["DecimalColumn"]))
     {
        decimalData = 0m;
     }
     else
     {
        decimalData = reader.GetDecimal(reader.GetOrdinal("DecimalColumn"));
     }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文