Convert xml to custom class using lambda linq

Attempting to parse an xml document to a custom class which I have created. I have successfully figured out how to parse the document, but for some reason I am having to do it into an IEnumerable instead of just a single instance of my custom class. Much easier to just show the code than explain in depth, so please see code snippets below.

Working Code

IEnumerable<Ping> ping = xmlDoc.Descendants("PING_SEND").Select(p => new Ping
    {
        TRAN_ID = (string)p.Element("TRAN_ID"),
        MILOC = (string)p.Element("MILOC"),
        TRANDATE = (string)p.Element("TRANDATE"),
        TRANTIME = (string)p.Element("TRANTIME"),
        COUNTRY = (string)p.Element("COUNTRY")
    });

Which Results in having to use...

foreach (Ping p in ping)
{
    cmd.Parameters.AddWithValue("@TRAN_ID", p.TRAN_ID);
    cmd.Parameters.AddWithValue("@MILOC", p.MILOC);
    cmd.Parameters.AddWithValue("@SITE_REF", "");
}

... when adding parameters to insert into the database. What I have tried (and need) is something that would be more in the vein of this...

Desired Code idea

Ping ping =(Ping)xmlDoc.Descendants("PING_SEND").Select(p => new Ping
    {
        TRAN_ID = (string)p.Element("TRAN_ID"),
        MILOC = (string)p.Element("MILOC"),
        TRANDATE = (string)p.Element("TRANDATE"),
        TRANTIME = (string)p.Element("TRANTIME"),
        COUNTRY = (string)p.Element("COUNTRY")
    });

//... Other operations and database functions...

cmd.Parameters.AddWithValue("@TRAN_ID", ping.TRAN_ID);
cmd.Parameters.AddWithValue("@MILOC", ping.MILOC);
cmd.Parameters.AddWithValue("@SITE_REF", "");
Jon Skeet
people
quotationmark

It sounds like all you need is a call to First() or Single() or whatever - to say that you only want one result (the first or only result - other options are available):

Ping ping = xmlDoc.Descendants("PING_SEND").Select(...).First();

Basically, the issue is that after Descendants(...).Select(...) you've got a sequence of Ping references, whereas you only want one.

If there might actually be multiple PING_SEND elements - or none - you really need to think about what you want to do in that situation. LINQ provides various methods to help, depending on your requirements:

  • First
  • Single
  • Last
  • FirstOrDefault
  • SingleOrDefault
  • LastOrDefault

The OrDefault methods allow you to handle the case where there are no results.

people

See more on this question at Stackoverflow