[英]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.