Linq查询返回null WhereEnumerableIterator<>

时间:2011-02-20 20:01:42

标签: c# linq linq-to-xml xelement

我正在尝试在c#4.0中进行过滤xlinq查询,因此我可以绑定到DataContext。代码是这样的:

public IEnumerable<XElement> Filter(int min = 0, int max = int.MaxValue)
{
    IEnumerable<XElement> selected = (
        from x in xmlFile.Elements("Product")
        where (int)x.Element("Price") >= min &&
              (int)x.Element("Price") <= max
        select x);

    return selected;
}

xmlFile是一个加载了外部xml文件的XElement。 xml文件结构如下所示:

<Stock>
    <Product>
      <Name /> 
      <Price /> 
      <Quantity /> 
    </Product>
    ...
</Stock>

构建或运行时我没有遇到任何错误,但selected变量只获得null(即使没有where子句)。当我在调试时将鼠标悬停在变量上时,它显示类型System.Linq.Enumerable.WhereEnumerableIterator。如果我只是返回xmlFile,它会很好,但我真的需要进行过滤!


修改

据我研究过,问题出在“xmlFile.Elements(”Product“)”语句中。我不知道如何解释这个,所以我做了一个截图(在我的代码中我实际使用“Respuesto”代替“Products”,我在这里翻译它以使其更容易):

(它不会让我插入图片,因为我是新用户,但它在这里:http://i.stack.imgur.com/XTt8r.png

我在我的代码中使用此函数作为DataContext,如下所示:

gridpricelist.DataContext = Conn.Filter(min: Convert.ToInt32(minprice.Text),
                            max: Convert.ToInt32(maxprice.Text));

minprice和maxprice是文本框,KeyUp事件触发上面的函数


EDIT2

我弄清楚了,看看我的回答。但我无法解释为什么它会这样运作,有人可以帮我理解吗?

提前致谢!

3 个答案:

答案 0 :(得分:2)

如果您有“空”或“不存在”的价格元素,它将会中断

试试这个:

public static IEnumerable<XElement> Filter(int min = 0, int max = int.MaxValue)
{
    Func<XElement, int?> parse = p => {
        var element = p.Element("Price");

        if (element == null) {
            return null;
        }

        int value;

        if (!Int32.TryParse(element.Value, out value)) {
            return null;
        }

        return value;
    };

    IEnumerable<XElement> selected = (
        from x in xmlFile.Elements("Product")
        let value = parse(x)
        where value >= min &&
            value <= max
        select x);

    return arr;
}

答案 1 :(得分:1)

我已经弄明白了!虽然我不知道为什么Xlinq方法不起作用...这里的代码对我有用而不是查询:

    public XElement filter(int min = 0, int max = int.MaxValue)
    {            
        XElement filtered = new XElement("Stock");
        foreach (XElement product in xmlFile.Elements("Product"))
        {
            if ((int)product.Element("Price") >= min &&
                (int)product.Element("Price") <= max)
                    filtered.Add(product);
        }
        return filtered;
    }
如果有人给我解释,这将是很好的。感谢您的阅读

答案 2 :(得分:0)

您有两个问题:

  1. 当您在WhereEnumerableIterator上方徘徊并看到.Currentnull时,一切正常。 This is deferred execution at work.一些LINQ查询(这也适用于XLinq)直到你枚举它们才会执行,因此.Currentnull直到你使用它为止!当您在答案中使用foreach时,它会枚举迭代器并生成一个值。

  2. 您的初始代码无效,因为它返回了没有根元素的XML枚举,并且无论您的调用代码是什么,它都需要它具有根。您的答案将数据包装在<Stock>元素中。您可以像这样使用原始代码:

    public XElement Filter(int min = 0, int max = int.MaxValue)
    {
        var selected = (
            from x in xmlFile.Elements("Product")
            where (int)x.Element("Price") >= min &&
                  (int)x.Element("Price") <= max
            select x);
    
        return new XElement("Stock", selected);
    }