【问题标题】:Comparison operators not supported for type 'System.String[]''System.String[]' 类型不支持比较运算符
【发布时间】:2009-07-31 11:01:27
【问题描述】:

为什么会有这行:

var category = _dataContext.Categories.Where<Category>(p => p.Keywords.Split(' ').Contains<string>(context.Request.QueryString["q"])).First();

抛出 System.NotSupportedException:

类型“System.String[]”不支持比较运算符

我该如何解决? 谢谢。

【问题讨论】:

    标签: c# linq linq-to-sql exception


    【解决方案1】:

    所以您正在数据库中以空格分隔的列中查找值(来自查询字符串)?而您正在使用Split 来查询数据库中的各个值?

    (只是检查我的假设......)

    string.Split 不支持以这种方式(在列数据的数据库中) - 请参阅此处以获取 supported string operations。 (请注意,string.Split明确不支持)。

    我很懒;当我在数据库中分隔数据时(相对较少),我总是在数据的开头和结尾添加相同的分隔符;然后我可以搜索:

    string searchFor = DELIMITER + searchValue + DELIMITER;
    ...
    .Where(row => row.Value.Contains(searchFor));
    

    但是;在这种情况下,我希望最实用的选择可能是编写一个 UDF 函数来搜索分隔的 varchar(正确处理第一个/最后一个项目),并在数据上下文中公开 UDF - 然后使用:

    .Where(row => ctx.ContainsValue(row.Value, searchValue)); // ContainsValue is our UDF
    

    或者 - 规范化数据...

    .Where(row => row.Values.Any(s=>s.Value == searchValue));
    

    【讨论】:

      【解决方案2】:

      string.split 在 LINQ-to-SQL 中不受支持。

      有一个简单的解决方法。选择所有数据并在客户端中进行过滤。根据类别的数量,这可能不是很有效。

      var category = 
          _dataContext.Categories.ToList()
          .Where<Category>(p => p.Keywords.Split(' ').Contains<string>(context.Request.QueryString["q"])).First();
      

      调用.ToList()会强制枚举你数据源中的所有类别,后续操作会在客户端代码中进行。

      【讨论】:

      • 将整个表读回给客户端几乎总是一个坏主意。在某些情况下它有效,但它们只是少数。
      • 确实,这可能会对性能造成巨大影响,但我们必须权衡这一点与普遍认为的预优化也不好的看法。除了会成为问题的大型项目外,可能还有无数的小型 Web 应用程序在这种情况下对性能的影响是微不足道的。我想这只是常识。
      【解决方案3】:

      context.Request.QueryString["q"] 可能返回一个字符串数组而不是单个字符串。这是因为一个url可能包含多个同名的参数。

      如果您确定请求中始终只有一个名为 q 的参数,您可以将代码更改为:context.Request.QueryString["q"].SingleOrDefault()

      【讨论】:

      • 刚刚检查过 - 它没有。它返回 "q1,q2,q3,q4,q5" 作为字符串,而不是数组。
      • HttpRequest.QueryString 是一个 NameValueCollection。
      • NameValueCollection 的索引器返回字符串-_-
      • 其实 - 我也是这么想的。但是发帖前查过了。 :)
      【解决方案4】:

      首先,我会避免在数据库中存储分隔数据。正如您发现的那样,它会使数据库查询等变得尴尬。

      如果您的类别数量有限,为了简单起见,我会选择 Joe 的答案,否则,会在 Marc 的方法中添加一些细节。

      1. 为我使用的 SQL Server 创建一个拆分式 UDF:
      CREATE FUNCTION FN_CHARLIST_TO_TABLE (@list nvarchar(MAX), @delimiter nchar(1) = N',') RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL, str varchar(4000) NOT NULL, nstr nvarchar(2000) NOT NULL) AS /* Comments: - Takes a CSV string, and creates a table of data from this - Each item takes one row in the following format listpos - the index of the item in the string (effectively a row number in the output) str - The value, as VARCHAR nstr - The value, as NVARCHAR - This function is a direct extract from http://www.sommarskog.se/arrays-in-sql-2005.html#iter-list-of-strings Usage: SELECT * FROM t JOIN FN_CHARLIST_TO_TABLE('a,b,c,1,2,3', ',') list ON t.Name = list.str */ BEGIN DECLARE @endpos int, @startpos int, @textpos int, @chunklen smallint, @tmpstr nvarchar(4000), @leftover nvarchar(4000), @tmpval nvarchar(4000) SET @textpos = 1 SET @leftover = '' WHILE @textpos 0 BEGIN SET @tmpval = ltrim(rtrim(substring(@tmpstr, @startpos + 1, @endpos - @startpos - 1))) INSERT @tbl (str, nstr) VALUES(@tmpval, @tmpval) SET @startpos = @endpos SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2, @tmpstr, @startpos + 1) END SET @leftover = right(@tmpstr, datalength(@tmpstr) / 2 - @startpos) END INSERT @tbl(str, nstr) VALUES (ltrim(rtrim(@leftover)), ltrim(rtrim(@leftover))) RETURN END
      1. 将此添加到您的 DBML 文件中
      2. 查询您的数据库,适当地引用 UDF
      
      var catergories = from cat in _datacontext.Categories
                        from keyword in _datacontext.FN_CHARLIST_TO_TABLE(cat.Keywords, ' ')
                        where keyword.str == context.Request.QueryString["q"]
                        select cat;
      

      这将执行一个纯粹的数据库端查询。

      【讨论】:

        【解决方案5】:

        1) ToList() 你的 var 查询

        2) 在第一步生成的列表中编写包含和拆分查询:它执行正确

        祝你好运

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多