结果查询中的值错误,因此 Linq 查询中出现空引用异常

本文关键字:查询 异常 Linq 引用 错误 结果 因此 | 更新日期: 2023-09-27 18:30:31

我有两个xml文件,我正在相互比较。Linq 查询result1在正确执行一个rule后引发Null Reference Exception。当我调试时,我发现section显示错误的值。我无法找出原因。

规则.xml文件:

<rule id="1" numberofsections="2">
  <section id="1" attributeid="1686" ruleoperator="=="  condition="and">
    <name>Processor type</name>
    <value>Core i3</value>
  </section>
  <section id="2" attributeid="1438" ruleoperator="&lt;" condition="and" >
    <name>Weight</name>
    <value>3.8 LBS</value>
  </section>
  <type>ultrabook</type>
</rule> 

和代码片段:

XDocument rulesXml = XDocument.Load("/RulesEnginescope/RulesEnginescope/rulesSubType.xml");
XDocument productXml = XDocument.Load("c:/RuleEngine/RuleEngine/product.xml");
var getSelectedLeafCategoryRules = from rules2 in       rulesXml.Descendants("QueryTransformation").Descendants("leafcategory")
                                       where ((long)System.Convert.ToDouble(rules2.FirstAttribute.Value) == 4590)
                                       select rules2;
    var rules = getSelectedLeafCategoryRules.Descendants("rule");
    var productAttribute = productXml.Descendants("AttrList").Descendants("Attr");
    foreach (var x in rules)
    {
        var section = x.Elements("section");          
       /*Wrong value in section.count()*/ 
        Console.WriteLine(section.Count());
       var result1 = from p in section
                      from pa in productAttribute
                      where (p.Attribute("attributeid").Value == pa.Attribute("id").Value
                       && p.Element("name").Value == pa.Element("Name").Value)
                      select new
                      {
                          ruleAttribute = new
                          {
                              ruleId = p.Attribute("attributeid").Value,
                              ruleOperator = p.Attribute("ruleoperator").Value,
                              name = p.Element("name").Value,
                              value = p.Element("value").Value,
                              condition = p.Attribute("condition").Value
                          },
                          prodAttribute = new
                          {
                              productId = pa.Attribute("id").Value,
                              name = pa.Element("Name").Value,
                              value = pa.Element("ValueList").Element("Value").Value
      /*Error*/                    }
                      };
        if (result1.Count() != 0 && result1.Count() == System.Convert.ToInt64(x.Attribute("numberofsections").Value))
        {
            //checking each section
            foreach (var r in result1)
            {
                ...
            }
    }

结果查询中的值错误,因此 Linq 查询中出现空引用异常

在 LINQ-to-XML 中获取元素和属性值的惯用方法是将元素或属性强制转换为所需的类型,而不是访问 Value 属性。

prodAttribute = new
                {
                   productId = (string)pa.Attribute("id"),
                   name = (string)pa.Element("Name"),
                   // ...
                }

使用此模式可避免在调用 Attribute()Element() 找不到匹配节点时导致的 null ref 异常。它还可以减少冗长:

((long)System.Convert.ToDouble(rules2.FirstAttribute.Value)
// should be 
(long)rules2.FirstAttribute

在访问子项的子项时,仍需要添加空检查。这可能会变得冗长;保持简洁的一种方法是使用面向 IEnumerable 的方法,以便您在(可能是空的)集合上进行操作,而不是在(可能是空的)实例上操作。

pa.Element("ValueList").Element("Value").Value
// could be
(string)pa.Elements("ValueList").Elements("Value").FirstOrDefault ()

最后,请注意,大写在 LINQ to XML 中很重要。在您的代码中,您似乎经常切换大写模式("id"与"名称");源 XML 可能更加一致。