开发者

Xlinq query returning null WhereEnumerableIterator<>

i'm trying to do a filtering xlinq query in c# 4.0, so i can bind to a DataContext. the code is this:

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 is an XElement with an external xml file loaded. the xml file structure looks something like this:

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

I don't get any errors when building or running, but the selected variable gets only null (even without the where clause). When I hover the mouse over the variable when debugging, it shows the type System.Linq.Enumerable.WhereEnumerableIterator. If I just return the xmlFile, it goes fine, but I really need to do the filtering!


EDIT

as far as I've researched, the problem is on the "xmlFile.Elements("Product")" statement. I don't know how to explain this, so I made a screenshot (in my code I actually use "Respuesto" in place of "Products", I translated it here to make it easier):

(It won't let me insert an image because i'm a new user, but it es here: http://i.stack.imgur.com/XTt8r.png

I use this function in my code as a DataContext like this:

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

minprice and maxprice are textboxes, and a KeyUp event triggers the function from above


EDIT2

I figured it out, see my answer. But I can't explain why it works that way, could someone help me understand?

Thanks in advance!


If you have "empty" or "not existing" price elements it will break

Try this:

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;
}


I have figured it out! Although I don't know why the Xlinq approach doesn't work... here is the code that worked for me instead of the query:

    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;
    }

that would be great if someone gives me an explain. thanks for reading


You have two issues:

  1. When you hovered over the WhereEnumerableIterator and saw .Current was null, everything was working normally. This is deferred execution at work. Some LINQ queries (this applies to XLinq too) do not execute until you enumerate them, hence .Current will be null until you use it! When you used foreach in your answer it enumerated the iterator and produced a value.

  2. Your initial code did not work as it returned an enumeration of XML without a root element, and it appears whatever your calling code is it required it to have a root. Your answer wraps the data in a <Stock> element. You can use your original code like so:

    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);
    }
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜