tags:

views:

254

answers:

2

is there a better way to do this kind of thing:

var filter = new CashFilters();
var element = XElement.Parse(request.OuterXml);

var productId = element.Elements("ProductId").Select(el => el);

if (productId.Count() == 1)
    filter.ProductId = Convert.ToInt32(productId.Single().Value);
+2  A: 

Well, the Select(el => el) isn't doing you any good to start with.

I suggest you use SingleOrDefault:

var productId = element.Elements("ProductId").SingleOrDefault();
if (productId != null)
    filter.ProductId = Convert.ToInt32(productId.Value);

Note that that handles the case where there are no ProductId elements, but will throw an exception if there's more than one. If that's actually a valid case, then your current code (without the redundant Select call) is reasonable.

EDIT: You could get away from this with:

var productId = element.Elements("ProductId")
                       .Select(elt => elt.Value)
                       .SingleOrDefault();
filter.ProductId = Convert.ToInt32(productId ?? filter.ProductId.ToString());

But that's pretty ghastly ;)

Basically you've got a condition - you only want to set the ProductId if it's specified. An "if" statement is the generally accepted way of conditionally executing code :)

There are alternatives:

filter.ProductId = productId == null 
                   ? filter.ProductId 
                   : int.Parse(productId);

If you don't mind filter.ProductId being set to 0 if there's no ID specified, then you can just use:

filter.ProductId = Convert.ToInt32(element.Elements("ProductId")
                                          .Select(elt => elt.Value)
                                          .SingleOrDefault());

(due to the way that Convert.ToInt32 returns 0 when passed a null argument.)

Jon Skeet
so there's no way to get ride of the null check?great book by the way :)
AWC
+1  A: 

Do you REALLY need to do this in Linq to Xml? The Xml DOM approach seems much more reasonable to me.

Have you considered the pure Xml approach?

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(request.OuterXml);

    var node = doc.SelectSingleNode("//ProductId[1]");
    if (node != null)
        filter.ProductId = Convert.ToInt32(node.InnerText);
Jeff Fritz
Personally I prefer the LINQ to XML approach - less scary (uncompiled) string stuff to go wrong. Simply using Elements("ProductId").SingleOrDefault() does the same as the XPath expression, but with less to know IMO.
Jon Skeet