我正在尝试在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
我弄清楚了,看看我的回答。但我无法解释为什么它会这样运作,有人可以帮我理解吗?
提前致谢!
答案 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)
您有两个问题:
当您在WhereEnumerableIterator
上方徘徊并看到.Current
为null
时,一切正常。 This is deferred execution at work.一些LINQ查询(这也适用于XLinq)直到你枚举它们才会执行,因此.Current
将null
直到你使用它为止!当您在答案中使用foreach
时,它会枚举迭代器并生成一个值。
您的初始代码无效,因为它返回了没有根元素的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);
}