为什么这个 LINQ 会抛出 "FormatException was unhandled"?
Why does this LINQ throw "FormatException was unhandled"?
我正在尝试使用 LINQ 从通用列表中获取一个 val,如下所示:
private List<PriceVarianceDataAmalgamated> CombineSubsets(string unit)
{
List<PriceVarianceDataAmalgamated> combinedSubsets = new List<PriceVarianceDataAmalgamated>();
if (unit.Equals(CRAFTWORKS_SC))
{
foreach (PriceVarianceSubsetData pvsd in craftworksWeek1PVDSubsetList)
{
PriceVarianceDataAmalgamated pvda = new PriceVarianceDataAmalgamated
{
ShortName = pvsd.ShortName,
ItemCode = pvsd.ItemCode,
Description = pvsd.Description,
Price1 = pvsd.Price,
Price2 = GetPrice2(CRAFTWORKS_SC, pvsd.ShortName, pvsd.ItemCode)
};
pvda.Variance = "0.00";
decimal price1 = Convert.ToDecimal(pvda.Price1);
decimal price2 = Convert.ToDecimal(pvda.Price2);
. . .
关键部分(未能按我的意愿行事)是对 GetPrice2() 的调用。该方法开始于:
private string GetPrice2(string _unit, string _shortname, string _itemcode)
{
string price2 = "0.00";
if (_unit.Equals(CRAFTWORKS_SC))
{
price2 = craftworksWeek2PVDSubsetList
.Where(x => x.ShortName.Equals(_shortname))
.Where(x => x.ItemCode.Equals(_itemcode))
.Select(x => x.Price).ToString();
}
. . .
...当我在那里进入对 price2 的赋值时,赋值的值是:
System.Linq.Enumerable+WhereSelectListIterator`2[Pivotal.PriceVarianceSubsetData,System.String]
?!?
给出的错误消息是:
System.FormatException was unhandled
HResult=-2146233033
Message=Input string was not in a correct format.
Source=mscorlib
StackTrace:
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
at System.Convert.ToDecimal(String value)
at Pivotal.FormMain.CombineSubsets(String unit) in c:\Projects\PriceVariance\Pivotal\Form1.cs:line 290
at Pivotal.FormMain.GenerateAndSaveSpreadsheetFile() in c:\Projects\PriceVariance\Pivotal\Form1.cs:line 154
at Pivotal.FormMain.buttonRun_Click(Object sender, EventArgs e) in c:\Projects\PriceVariance\Pivotal\Form1.cs:line 137
. . .
所以这一行 (290) 失败了:
List<PriceVarianceDataAmalgamated> pvdaCraftworks = CombineSubsets(CRAFTWORKS_SC);
...更具体地说是这个(第 154 行):
decimal price2 = Convert.ToDecimal(pvda.Price2);
显然错误的代码是这样的:
price2 = craftworksWeek2PVDSubsetList
.Where(x => x.ShortName.Equals(_shortname))
.Where(x => x.ItemCode.Equals(_itemcode))
.Select(x => x.Price).ToString();
在它爆炸的地方逐步通过它,“_shortname”和“_itemcode”都有一个有效值; select 完全有可能没有价值,但我似乎通过为 price2:
分配默认值来抵御这种情况
string price2 = "0.00";
price2 在方法结束时返回 - 也许我应该使用 catch 块并在那里分配回退值而不是从 git-go?
price2
被声明为 string
但您的 LINQ 查询已被写入,因此它可能 return 一个列表。
FormatException
让我觉得您可能正在取回多个项目并试图将该结果推入单个变量。对局部变量使用 var
有助于暴露这个问题。
AlexD 建议 .Select(x => x.Price).First().ToString()
。我认为这将确保您只得到一个结果。
您可能还想考虑 .Distinct()
以确保获得单一类型的结果。如果不首先确保没有多种类型的答案,select 第一项就没有多大意义。
使用
.Select(x => x.Price).FirstOrDefault().ToString();
不会抛出异常,而是为引用类型返回空值,为值类型返回默认值。可能会让您更容易找到问题所在
我正在尝试使用 LINQ 从通用列表中获取一个 val,如下所示:
private List<PriceVarianceDataAmalgamated> CombineSubsets(string unit)
{
List<PriceVarianceDataAmalgamated> combinedSubsets = new List<PriceVarianceDataAmalgamated>();
if (unit.Equals(CRAFTWORKS_SC))
{
foreach (PriceVarianceSubsetData pvsd in craftworksWeek1PVDSubsetList)
{
PriceVarianceDataAmalgamated pvda = new PriceVarianceDataAmalgamated
{
ShortName = pvsd.ShortName,
ItemCode = pvsd.ItemCode,
Description = pvsd.Description,
Price1 = pvsd.Price,
Price2 = GetPrice2(CRAFTWORKS_SC, pvsd.ShortName, pvsd.ItemCode)
};
pvda.Variance = "0.00";
decimal price1 = Convert.ToDecimal(pvda.Price1);
decimal price2 = Convert.ToDecimal(pvda.Price2);
. . .
关键部分(未能按我的意愿行事)是对 GetPrice2() 的调用。该方法开始于:
private string GetPrice2(string _unit, string _shortname, string _itemcode)
{
string price2 = "0.00";
if (_unit.Equals(CRAFTWORKS_SC))
{
price2 = craftworksWeek2PVDSubsetList
.Where(x => x.ShortName.Equals(_shortname))
.Where(x => x.ItemCode.Equals(_itemcode))
.Select(x => x.Price).ToString();
}
. . .
...当我在那里进入对 price2 的赋值时,赋值的值是:
System.Linq.Enumerable+WhereSelectListIterator`2[Pivotal.PriceVarianceSubsetData,System.String]
?!?
给出的错误消息是:
System.FormatException was unhandled
HResult=-2146233033
Message=Input string was not in a correct format.
Source=mscorlib
StackTrace:
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
at System.Convert.ToDecimal(String value)
at Pivotal.FormMain.CombineSubsets(String unit) in c:\Projects\PriceVariance\Pivotal\Form1.cs:line 290
at Pivotal.FormMain.GenerateAndSaveSpreadsheetFile() in c:\Projects\PriceVariance\Pivotal\Form1.cs:line 154
at Pivotal.FormMain.buttonRun_Click(Object sender, EventArgs e) in c:\Projects\PriceVariance\Pivotal\Form1.cs:line 137
. . .
所以这一行 (290) 失败了:
List<PriceVarianceDataAmalgamated> pvdaCraftworks = CombineSubsets(CRAFTWORKS_SC);
...更具体地说是这个(第 154 行):
decimal price2 = Convert.ToDecimal(pvda.Price2);
显然错误的代码是这样的:
price2 = craftworksWeek2PVDSubsetList
.Where(x => x.ShortName.Equals(_shortname))
.Where(x => x.ItemCode.Equals(_itemcode))
.Select(x => x.Price).ToString();
在它爆炸的地方逐步通过它,“_shortname”和“_itemcode”都有一个有效值; select 完全有可能没有价值,但我似乎通过为 price2:
分配默认值来抵御这种情况string price2 = "0.00";
price2 在方法结束时返回 - 也许我应该使用 catch 块并在那里分配回退值而不是从 git-go?
price2
被声明为 string
但您的 LINQ 查询已被写入,因此它可能 return 一个列表。
FormatException
让我觉得您可能正在取回多个项目并试图将该结果推入单个变量。对局部变量使用 var
有助于暴露这个问题。
AlexD 建议 .Select(x => x.Price).First().ToString()
。我认为这将确保您只得到一个结果。
您可能还想考虑 .Distinct()
以确保获得单一类型的结果。如果不首先确保没有多种类型的答案,select 第一项就没有多大意义。
使用
.Select(x => x.Price).FirstOrDefault().ToString();
不会抛出异常,而是为引用类型返回空值,为值类型返回默认值。可能会让您更容易找到问题所在