Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 包含Linq to XML Where子句中的功能_C#_.net_Linq To Xml - Fatal编程技术网

C# 包含Linq to XML Where子句中的功能

C# 包含Linq to XML Where子句中的功能,c#,.net,linq-to-xml,C#,.net,Linq To Xml,Linq to XML中where子句的.Contains()函数出现意外行为。它的功能似乎与字符串函数中的“==”not Contains()类似 例如: var q = from sr in SearchResults.Descendants("Result") where _filters.Contains((string)sr.Element("itemtype")) orderby (string)sr.Element("ipitemtype") ascending

Linq to XML中where子句的.Contains()函数出现意外行为。它的功能似乎与字符串函数中的“==”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"),
    }
_筛选器是字符串的列表。假设它包含3个值:

_filters[0] = "videos";
_filters[1] = "documents";
_filters[2] = "cat pictures";
现在的情况是,如果

<itemtype>videos</itemtype> 

试试这个:

_filters.Any(s => ((string)sr.Element("itemtype") ?? "").Contains(s))
where _filters.Any(filter => ((string)sr.Element("itemtype")).Contains(filter))
通过这种方式,您可以检查元素的值是否包含
\u过滤器中的任何字符串。使用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)

您正在检查数组
\u过滤器
是否有值为
的元素“videos mission Critical document advertising”(并非如此),而不是
“videos mission Critical document advertising”
是否包含
\u过滤器中的任何元素

试试这个:

_filters.Any(s => ((string)sr.Element("itemtype") ?? "").Contains(s))
where _filters.Any(filter => ((string)sr.Element("itemtype")).Contains(filter))

问题是你对方法的工作方式做出了错误的假设。(另请参见contains方法,如果“序列包含特定元素”,则返回true。在您描述的示例中,
\u过滤器
数组和
项目类型
文本都包含字符串
视频
,但两者都不包含。更合适的测试是使用以下扩展方法:

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

查看此帖子也可能会有所帮助:,它类似于但专门针对
字符串。Contains
方法,而不是
可枚举。Contains
扩展。

我不认为这是真的,如果节点包含单个值,如videos,那么Linq会返回该节点,而不是来自_filters.interest的字符串。因此我尝试了你的代码,现在我遇到了相反的问题。只是视频的节点被忽略,而像营销传播视频这样的节点被接受。真的很困惑。如果结果是
null
,使用
Contains
,这里会抛出
NullReferenceException
。我已经更新了我的响应来处理这个问题塞纳里奥。请查看我的新答案-原来的答案是错误的。ContainsAny现在对我来说不是一个可用的选项。如果这有什么不同,我将使用Silverlight,但我检查了一下以确保我的.NET framework是版本4。@Wesley,你说它不可用是什么意思?我发布了代码。复制并粘贴到你的解决方案中。@smartcaveman当一个简单的LINQ语句可以完成任务时,这是一个非常麻烦的过程。我做了,ContainsAny显示“字符串不包含ContainsAny的定义”。我现在正在研究这个问题。@Ahmad Mageed你指的是一个单独的LINQ语句。这就是我现在正在做的,但是使用两个语句,其中一个带有正确的where,似乎很愚蠢。我的问题是,如果项没有正确标记,有时可能是空的。如果元素为空,即。Value抛出异常,这就是为什么我总是对字符串进行大小写,而不是依赖于.Value。@Wesley尝试更新的方法。这使用
let
保留显式转换结果,如果该结果为空,则将其过滤掉,然后对照过滤项进行检查。**EDIT我尝试了该方法,枚举结果完全为空。不是真的,结果为空有一些结果,但不是全部。@Wesley在你发表评论之前,我在文章底部又添加了一个更新。你的过滤器或值可能包含大小写混合。使用我上面概述的
IndexOf
方法忽略过滤器和元素值的大小写。如果这不起作用,那么问题就出在别处。艾哈迈德,确实有一个案例问题是另一个团队糟糕代码的一部分。这个问题已经解决,所有XML都设置为小写。你的解决方案有效,但其他人的速度更快,他们的代码更干净,所以我将他们的代码标记为答案。不过我会投票,你做得很好。
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;
    }
}
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
        };