2016-07-05 35 views
2

我试图让使用LINQ从一个普通的列表VAL像这样:为什么这个LINQ抛出“FormatException未处理”?

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那里,被分配了val为:

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”都有一个有效值;这是完全可能是没有价值的选择,但我似乎被赋予一个默认值price2进行防御是:

string price2 = "0.00"; 

price2是在方法的最后返回 - 也许我应该使用catch块并在那里分配fallback值,而不是从git-go?

+3

尝试'.Select(x => x.Price).First()。ToString();' – AlexD

+1

您的更具体的行与早前的 –

+1

完全相同我同意与之前一样,但使用不会抛出异常的FirstOrDefault,而是返回空值作为引用类型和值类型的默认值。可以让你更容易找到问题所在。 –

回答

2

使用

.Select(x => x.Price).FirstOrDefault().ToString(); 

它不需额外抛出一个异常,而不是返回引用类型和值类型默认值的空值。可以让你更容易找到问题所在

+0

“.ToString()”似乎是冗余/模拟。没有它就可以正常工作,并且添加它会显得灰色。 –

+1

这对我来说是新东西,但我想有一些LINQ的新功能。我的猜测是自从你声明变量“string price2 =”0.00“;”作为一个字符串而不是var,不知怎的,查询已经知道要将其转换为什么。感谢您的意见,我将不得不看看。 –

1

price2被声明为string但您的LINQ查询已写入,以便它可能会返回一个列表。

FormatException让我觉得你可能会得到多个项目并尝试将该结果推送到单个变量中。对局部变量使用var将有助于揭示此问题。

AlexD建议.Select(x => x.Price).First().ToString()。我认为这将确保你只有一个结果。

您可能还想考虑.Distinct()以确保您获得单一类型的结果。没有首先确定没有多种类型的答案,选择第一项就没有多大意义。

相关问题