在';和';和';或者';linq中的filter到c#中的xml
本文关键字:中的 xml 或者 linq filter | 更新日期: 2023-09-27 17:58:56
是否可以在linq to xml中将过滤器约束设置为"OR"?我在一个数组中进行迭代,以过滤所需的值,如下所示:
XElement root = XElement.Load(fileName);
IEnumerable<XElement> selectedElements = root.Elements("OrderNum").Elements("Job");
for (int i = 1; i < chkBx.Count(); i++)
{
if (chkBx[i].Checked == true)
{
string element = "Diameter";
string match = chkBx[i].Text;
selectedElements = selectedElements.Where(el => (string)el.Parent.Element(element) == match);
}
}
现在,过滤器将通过"AND"语句链接在一起。如果我想选择一个元素来统计这些筛选条件中的任何一个,该怎么办?
var filters = chkBx.Where(r => r.Checked).Select(r => r.Text).ToList();
selectedElements = selectedElements.Where(r =>
filters.Contains((string)r.Parent.Element(element)))
您有三个选项,具体取决于场景:
- 您可以每次
.Union
查询(我怀疑这可能会产生大量开销) - 您可以构建一个自定义表达式(需要做大量工作,但实际上并不适合LINQ to Objects)
- 你可以建立一个匹配的
HashSet<string>
(我的首选)
即
HashSet<string> matches = new HashSet<string>();
// this next bit can probably be simplified, perhaps using LINQ;
// left alone as it is orthogonal
for (int i = 1; i < chkBx.Count(); i++)
{
if (chkBx[i].Checked == true)
{
string element = "Diameter";
matches .Add(chkBx[i].Text);
}
}
var selectedElements = selectedElements.Where(el =>
matches.Contains((string)el.Parent.Element(element)));
您可以通过两种方式来实现这一点,其中一种方式是使用表达式树构建表达式(对于IQueryable情况是必要的)。但是,由于您在查询内存中的模型,因此可以维护一个谓词列表,并使用Any
扩展来进行筛选。
var predicates = new List<Func<XElement, bool>>();
for (int i = 1; i < chkBx.Count(); i++)
{
if (chkBx[i].Checked)
{
var match = chkBx[i].Text;
predicates.Add(el => (string)el.Parent.Element("Diameter") == match)
}
}
selectedElements = selectedElements.Where(el => predicates.Any(p => p(el)));