6

我正在尝试解决使用 LINQ 的错误。我正在使用 LINQ 提取 XML 节点值。我面临的问题是当节点不存在于 XML 中时,我会Sequence contains no elements出错。我尝试使用 DefaultIfEmpty、Singleordefault 和 Firstordefault。但随后它会引发空指针异常。我想我不是正确的方法。如何使用其中之一来解决问题?

这是我正在使用的 LINQ 代码。

var costnode6 = doc.Root.Descendants(ns + "SERVICEUPGRADES").Single(c => (string)c.Element(ns + "DELIVERYTIME") == "before 3:30 PM").Element(ns + "TOTAL_COST");
        var cost6 = (decimal)costnode6;
4

2 回答 2

7

The OrDefault methods return the default value for the type if there is no result, which in your case would be null. That means when you do a .Element(ns + "TOTAL_COST") after that call, you'll get the Sequence contains no elements error if using Single or a Null Reference Exception if using SingleOrDefault.

What you should do is pull the call out and check the result against null:

var deliveryTime = doc.Root.Descendants(ns + "SERVICEUPGRADES")
    .SingleOrDefault(c => (string)c.Element(ns + "DELIVERYTIME") == "before 3:30 PM");
if(deliveryTime != null)
{     
    var costnode6 = deliveryTime.Element(ns + "TOTAL_COST");
    var cost6 = (decimal)costnode6;   
}
于 2013-08-08T00:23:08.097 回答
3

Use SingleOrDefault, but then have a guard clause before trying to use costnode6, like this:

var costnode6 = doc.Root.Descendants(ns + "SERVICEUPGRADES").SingleOrDefault(c => (string)c.Element(ns + "DELIVERYTIME") == "before 3:30 PM").Element(ns + "TOTAL_COST");

if(costnode6 != null)
{
    var cost6 = (decimal)costnode6;
}

This will protect your LINQ query from blowing up, because the OrDefault will make the query result null if exactly one result is not found; and the if condition will protect you from trying to use a null object.

于 2013-08-08T00:21:43.293 回答