[英]Contains functionality in Linq to XML Where Clause
我在 Linq 到 XML 的 where 子句的它的功能似乎类似于字符串 function 中的“==”not Contains()。
例子:
var q = from sr in SearchResults.Descendants("Result")
where _filters.Contains((string)sr.Element("itemtype"))
orderby (string)sr.Element("ipitemtype") ascending
select new SearchItem
{
//Create Object
ID = (string)sr.Element("blabla"),
}
_filters 是一个字符串列表。 假设它包含 3 个值:
_filters[0] = "videos";
_filters[1] = "documents";
_filters[2] = "cat pictures";
现在发生的情况是,如果 Query 完美运行
<itemtype>videos</itemtype>
是 XML 节点。
但是,如果节点是
<itemtype>videos mission critical document advertising</itemtype>,
IEnumerable 返回空白,这对我来说说操作数的功能类似于“==”而不是“Contains()”。
知道我做错了什么吗?
来自 dtb 的获奖答案:
代替
where _filters.Contains((string)sr.Element("itemtype"))
和
where _filters.Any(filter => ((string)sr.Element("itemtype")).Contains(filter))
尝试这个:
_filters.Any(s => ((string)sr.Element("itemtype") ?? "").Contains(s))
这样您就可以检查元素的值是否包含_filters
中的任何字符串。 使用 null 合并运算符可确保在itemtype
节点不存在时不会引发NullReferenceException
,因为它被替换为空字符串。
另一种方法是使用let
并过滤掉空值:
var q = from sr in SearchResults.Descendants("Result")
let itemtype = (string)sr.Element("itemtype")
where itemtype != null &&
_filters.Any(filter => itemtype.Contains(filter))
orderby (string)sr.Element("ipitemtype") ascending
select new SearchItem
{
//Create Object
ID = (string)sr.Element("blabla")
}
请注意, String.Contains
区分大小写。 因此,对“视频”的检查不会与带有大写字母“V”的“视频”匹配。 要忽略大小写,您可以使用String.IndexOf
这种方式:
_filters.Any(filter => itemtype.IndexOf(filter, StringComparison.InvariantCultureIgnoreCase) >= 0)
您正在检查数组_filters
是否具有值为"videos mission critial document advertising"
的元素(不是这种情况),而不是"videos mission critial document advertising"
是否包含_filters
中的任何元素。
尝试这个:
where _filters.Any(filter => ((string)sr.Element("itemtype")).Contains(filter))
问题是您对Contains方法的工作方式做出了错误的假设。 (另请参阅String.Contains()
文档如果“序列包含特定元素”,则 contains 方法返回 true。在您描述的示例中, _filters
数组和itemtype
文本都包含字符串videos
,但彼此都不包含。更合适的测试是使用以下扩展方法:
public static class ContainsAnyExtension
{
public static bool ContainsAny<T>(this IEnumerable<T> enumerable, params T[] elements)
{
if(enumerable == null) throw new ArgumentNullException("enumerable");
if(!enumerable.Any() || elements.Length == 0) return false;
foreach(var element in elements){
if(enumerable.Contains(element)){
return true;
}
}
return false;
}
}
因此,您正确的 LINQ 查询将是:
var q = from sr in SearchResults.Descendants("Result")
where ((string)sr.Element("itemtype")).ContainsAny(_filters)
orderby ((string)sr.Element("ipitemtype")) ascending
select new SearchItem
{
ID = sr.Element("blabla").Value
};
查看这篇文章也可能会有所帮助: 我如何使用 LINQ Contains(string[]) 而不是 Contains(string) ,它类似但专门针对String.Contains
方法而不是Enumerable.Contains
扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.