开发者

How do I write this as non-LINQ code?

开发者 https://www.devze.com 2023-04-01 09:40 出处:网络
I found some example of开发者_如何转开发 how to read the XML from an Excel spreadsheet >> HERE <<, and I am trying to get the code to work for me. I have to write a routine that takes the data f

I found some example of开发者_如何转开发 how to read the XML from an Excel spreadsheet >> HERE <<, and I am trying to get the code to work for me. I have to write a routine that takes the data from 4 of the 15 sheets in the workbook, and use that data to populate our database. Anyway....

This code is throwing an InvalidOperationException exception every time I attempt to query my Excel spreadsheet:

static XElement GetWorksheet(string sheetName, PackagePartCollection allParts) {
  XElement element = null;
  try {
    PackagePart worksheetPart = (from part in allParts
                                 where part.Uri.OriginalString.Equals(String.Format("/xl/worksheets/{0}.xml", sheetName))
                                 select part).Single();
    element = XElement.Load(XmlReader.Create(worksheetPart.GetStream()));
  } catch (Exception err) { // catches InvalidOperationException
    Console.WriteLine(err.Message);
  }
  return element;
}

The specific error is, "Sequence contains no elements"

I'm really not sure how to go about debugging it, because I'm not sure what the code is trying to do.

Could someone help me write it in Standard" C# before I try to implement the fancy LINQ expression? (that is LINQ, right?)

[Solved]

Using the snippet provided by JeffN825, I was able to create this:

static XElement GetWorksheet(string sheetName, PackagePartCollection allParts) {
  string xmlCompare = string.Format("/xl/worksheets/{0}.xml", sheetName);
  foreach (PackagePart part in allParts) {
    string original = part.Uri.OriginalString;
    if (original == xmlCompare) {
      XElement element = XElement.Load(XmlReader.Create(part.GetStream()));
      return element;
    }
  }
  return null;
}

It turns out that even though my sheet names in Excel are "HV", "M2", "CB" and "CC", I still have to specify them as "sheet2", "sheet3", "sheet4" and "sheet5".

I had to step through 161 PackagePart objects to see this.

LINQ is just so damn efficient that it can be hard to debug when there are problems.


The .Single() is what's throwing the exception. Either your query is returning no items or it's returning > 1 item. If you're not sure of the number of items you're expecting, you should be using FirstOrDefault() which will return the first match or null if no matches are found.

The non-LINQ equivalent is something like this

PackagePart worksheetPart = null
foreach(var part in allParts)
{
   if (part.Uri.OriginalString.Equals(String.Format("/xl/worksheets/{0}.xml", sheetName))))
   {
       if (part != null) throw new InvalidOperationException(); // > 1 match
       worksheetPart = part;
   }
}
if (part == null) throw new InvalidOperationException(); // no match


It's basically doing this.

PackagePart worksheetPart;

foreach(PackagePart part in allParts)
{
    if(part.Uri.OriginalString.Equals(String.Format("/xl/worksheets/{0}.xml", sheetName)))
    { 
        worksheetPart = part;
        break;
    }
}

In your version, try replacing .Single() with .FirstOrDefault().

It's failing because there is no match.


(from part in allParts
  where part.Uri.OriginalString.Equals(String.Format("/xl/worksheets/{0}.xml", sheetName))
  select part).Single();

Your error is in Single(). If your query has no values in it, Single() throws that exception. What you should use instead is SingleOrDefault(), which will return null if there's no values from the query.

0

精彩评论

暂无评论...
验证码 换一张
取 消