0

我有这个代码:

String testData = File.ReadAllText("siteQueryTest.txt");
XDocument xmlDoc = XDocument.Parse(testData);
List<SiteQuery> sitequeries =
 (from sitequery in xmlDoc.Descendants("SiteQuery")
  select new SiteQuery
  {
      Id = Convert.ToInt32(sitequery.Element("Id").Value),
      UPCPackSize = Convert.ToInt32(sitequery.Element("UPCPackSize").Value),
      UPC_Code = sitequery.Element("UPC_Code").Value,
      crvId = sitequery.Element("crvId").Value,
      dept = Convert.ToInt32(sitequery.Element("dept").Value),
      description = sitequery.Element("description").Value,
      openQty = Convert.ToDouble(sitequery.Element("openQty").Value),
      packSize = Convert.ToInt32(sitequery.Element("packSize").Value),
      subDept = Convert.ToInt32(sitequery.Element("subDept").Value),
      unitCost = Convert.ToDecimal(sitequery.Element("unitCost").Value),
      unitList = Convert.ToDecimal(sitequery.Element("unitList").Value),
      vendorId = sitequery.Element("vendorId").Value,
      vendorItem = sitequery.Element("vendorItem").Value,
  }).ToList<SiteQuery>();

测试数据是:

<SiteQueries><SiteQuery><Id>00006000002</Id><UPCPackSize>1</UPCPackSize><UPC_Code>00006000002</UPC_Code><crvId></crvId><dept>8</dept><description>ZZ</description><openQty>0.0</openQty><packSize>1</packSize><subDept>80</subDept><unitCost>1.25</unitCost><unitList>5.0</unitList><vendorId>CONFLICT</vendorId><vendorItem>123456</vendorItem></SiteQuery>
. . . // gazillions of other SiteQuery "records"
<SiteQuery><Id>5705654</Id><UPCPackSize>1</UPCPackSize><UPC_Code>5705654</UPC_Code><crvId></crvId><dept>2</dept><description>what do you want</description><openQty>0.0</openQty><packSize>1</packSize><subDept>0</subDept><unitCost>0.55</unitCost><unitList>1.62</unitList><vendorId></vendorId><vendorItem></vendorItem></SiteQuery></SiteQueries>

但是我得到以下代码和数据的运行时异常:

System.OverflowException was unhandled
  _HResult=-2146233066
  _message=Value was either too large or too small for an Int32.
  HResult=-2146233066
  IsTransient=false
  Message=Value was either too large or too small for an Int32.
  Source=mscorlib
  StackTrace:
       at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
       at System.Convert.ToInt32(String value)
       at Sandbox.Form1.<button56_Click>b__e(XElement sitequery) in c:\HoldingTank\Sandbox\Form1.cs:line 2041
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    . . .
  InnerException: 

每个xml“记录”中有几个int值(4);有数千条记录。我如何在不戴上雨人帽(不太适合我)的情况下确定哪个值是导致溢出或下溢的有问题的值?

如果它是下溢(异常 msg 表示“OverflowException”和“对于 Int32 来说值太大或太小”,这可能是由这四个 int 成员之一的空值引起的吗?如果是这样,我怎么能告诉它将空值视为0?

4

2 回答 2

4

这就是为什么大多数编码人员最终使用扩展方法而不是 LINQ 的原因。改写为:

private static SiteQuery ParseSiteQuery(XElement sitequery)
{
  return new SiteQuery
  {
      Id = Convert.ToInt32(sitequery.Element("Id").Value),
      UPCPackSize = Convert.ToInt32(sitequery.Element("UPCPackSize").Value),
      UPC_Code = sitequery.Element("UPC_Code").Value,
      crvId = sitequery.Element("crvId").Value,
      dept = Convert.ToInt32(sitequery.Element("dept").Value),
      description = sitequery.Element("description").Value,
      openQty = Convert.ToDouble(sitequery.Element("openQty").Value),
      packSize = Convert.ToInt32(sitequery.Element("packSize").Value),
      subDept = Convert.ToInt32(sitequery.Element("subDept").Value),
      unitCost = Convert.ToDecimal(sitequery.Element("unitCost").Value),
      unitList = Convert.ToDecimal(sitequery.Element("unitList").Value),
      vendorId = sitequery.Element("vendorId").Value,
      vendorItem = sitequery.Element("vendorItem").Value,
  };
}

然后做

List<SiteQuery> sitequeries = xmlDoc.Descendants("SiteQuery")
                                    .Select(ParseSiteQuery).ToList();

现在,当异常发生时,您将在这个转换函数内部中断,sitequery在范围内,立即了解是什么特定 XElement 导致了失败。

然后可以使用 quickwatch 表达式快速找出是什么初始化程序导致了异常。甚至为每个属性分配编写单独的语句。

于 2015-01-07T18:43:50.660 回答
0

这就是最终的工作:

   private void button42_Click(object sender, EventArgs e)
   {
       ArrayList arrList = 
    FetchSiteQuery("http://localhost:21608/api/sitequery/getall/dbill/ppus/42"); 
        String omnivore = "<SiteQueries>";
        foreach (String s in arrList) //- see siteQueryData.png
        {
            omnivore += s;
        }
        omnivore += "</SiteQueries>";

        String messedUpJunk = "<ArrayOfSiteQuery xmlns:i=\"http://www.w3.org/2001/XMLSchema-
    instance\" xmlns=\"http://schemas.datacontract.org/2004/07/CStore.DomainModels.HHS\">";
        omnivore = omnivore.Replace(messedUpJunk, String.Empty);
        omnivore = omnivore.Replace("</ArrayOfSiteQuery>", String.Empty);

        XDocument xmlDoc = XDocument.Parse(omnivore);
        List<SiteQuery> sitequeries = 
    xmlDoc.Descendants("SiteQuery").Select(GetSiteQueryForXMLElement).ToList();
    }

    private static SiteQuery GetSiteQueryForXMLElement(XElement sitequery)
    {
        return new SiteQuery
        {
            Id = sitequery.Element("Id").Value,
            UPCPackSize = Convert.ToInt32(sitequery.Element("UPCPackSize").Value),
            UPC_Code = sitequery.Element("UPC_Code").Value,
            crvId = sitequery.Element("crvId").Value,
            dept = Convert.ToInt32(sitequery.Element("dept").Value),
            description = sitequery.Element("description").Value,
            openQty = Convert.ToDouble(sitequery.Element("openQty").Value),
            packSize = Convert.ToInt32(sitequery.Element("packSize").Value),
            subDept = Convert.ToInt32(sitequery.Element("subDept").Value),
            unitCost = Convert.ToDecimal(sitequery.Element("unitCost").Value),
            unitList = Convert.ToDecimal(sitequery.Element("unitList").Value),
            vendorId = sitequery.Element("vendorId").Value,
            vendorItem = sitequery.Element("vendorItem").Value,
        };
    }
于 2015-01-07T19:50:26.297 回答