2016-07-05 7 views
2

나는과 같이 일반적인 목록에서 LINQ를 사용하여 발을 얻기 위해 노력하고 있어요 :이 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); 
      . . . 

핵심 부분 (즉 I가 원하는 것을 할 실패)() 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] 

?!?

주어진 ERR의 MSG

입니다

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 블록을 사용하고 git-go가 아닌 fallback 값을 할당 하시겠습니까?

+3

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

+1

더 구체적인 줄은 이전의 –

+1

과 동일합니다. 먼저, 예외를 throw하지 않는 FirstOrDefault를 사용하여 참조 유형과 값 유형의 기본값을 null 값으로 반환합니다. 문제가있는 곳을 쉽게 찾을 수 있습니다. –

답변

2

사용하는 대신 참조 유형 및 값 유형에 대한 디폴트 값에 대한 널 (null) 값을 리턴 예외를 발생 이뤄져

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

. 문제가있는 곳을 쉽게 찾을 수 있습니다.

+0

".ToString()"이 중복/부적절한 것으로 보입니다. 그것은 그것없이 잘 작동하고 그것을 추가하면 회색으로 보입니다. –

+1

그건 나에게 새로운 것이지만 LINQ에 몇 가지 새로운 기능이 있다고 생각합니다. 내 생각 엔 변수 "string price2 ="0.00 ";" var 대신 문자열로, 어쨌든 쿼리는 이미 변환 대상을 알고 있습니다. 그 의견을 주셔서 감사 드리며, 제가 살펴 봐야 할 것이 있습니다. –

1

price2string으로 선언되어 있지만 잠재적으로 목록을 반환 할 수 있도록 LINQ 쿼리가 작성됩니다.

FormatException 내가 여러 항목을 다시 가져 와서 그 결과를 단일 변수로 푸시하려고한다고 생각하게 만듭니다. 로컬 변수에 var을 사용하면이 문제가 드러납니다.

AlexD는 .Select(x => x.Price).First().ToString()을 제안했습니다. 나는 이것이 당신이 단지 하나의 결과만을 얻게 할 것이라고 생각합니다.

.Distinct()에 대해 생각해보고 단일 유형의 결과를 얻고 싶을 수도 있습니다. 여러 종류의 답변이 없는지 먼저 확인하지 않고 첫 번째 항목을 선택하는 것은별로 의미가 없습니다.