【问题标题】:LINQ to Entities does not recognize the method 'Int32 IndexOf(System.String, System.StringComparison)' methodLINQ to Entities 无法识别方法“Int32 IndexOf(System.String, System.StringComparison)”方法
【发布时间】:2014-04-22 06:12:02
【问题描述】:

我已经使用下面的 Entityframework 执行了一个 linq 查询

GroupMaster getGroup = null;
getGroup = DataContext.Groups.FirstOrDefault(item => keyword.IndexOf(item.Keywords,StringComparison.OrdinalIgnoreCase)>=0 && item.IsEnabled)

执行此方法时出现如下异常

LINQ to Entities 无法识别方法 'Int32 IndexOf(System.String, System.StringComparison)' 方法,并且这个 方法不能被翻译成商店表达式。

默认情况下Contains()方法区分大小写,所以我需要再次转换为lower。除了contains方法还有什么方法可以检查字符串匹配吗?有没有解决indexOf方法问题的方法?

【问题讨论】:

  • 如果您公开 DataContext.Groups 对象的相关字段,我可能会改进答案。
  • Contains 在生成的 SQL 查询中转换为 LIKE 语句。事实上,LIKE 是区分大小写还是不区分大小写取决于数据库配置。更改您的数据库以执行不区分大小写的字符串比较并使用Contains
  • 这是一个实体框架datacontext,其中Group为DbSet
  • 如果它不是 SqlFunctions msdn.microsoft.com/de-de/library/… 的一部分,您必须使用 LINQ 对象来查询实体。
  • 实际上里面包含方法我认为他们正在检查相同的功能索引然后为什么实体框架抛出异常。

标签: c# .net linq entity-framework


【解决方案1】:

你真的只有四个选择。

  1. 全局更改数据库的排序规则。这可以通过多种方式完成,一个简单的谷歌搜索就会发现它们。
  2. 更改单个表或列的排序规则。
  3. 使用存储过程并在查询中指定 COLATE 语句
  4. 执行查询并返回大量结果,然后使用 Linq to Objects 在内存中进行过滤。

数字 4 不是一个好的选择,除非您的结果集非常小。 #3 如果你不能改变数据库很好(但你不能使用 Linq)。

数字 1 和 2 是您需要对整个数据模型做出的选择,或者如果您只想对特定字段进行选择。

更改服务器排序规则: http://technet.microsoft.com/en-us/library/ms179254.aspx

更改数据库排序规则: http://technet.microsoft.com/en-us/library/ms179254.aspx

更改列排序规则: http://technet.microsoft.com/en-us/library/ms190920(v=sql.105).aspx

在存储过程中使用 Collat​​e 语句: http://technet.microsoft.com/en-us/library/ms184391.aspx

【讨论】:

    【解决方案2】:

    实体框架无法识别字符串类的IndexOf方法,请将此函数替换为SQLfunctionCanonical functions

    您也可以向herehere 寻求帮助

    您可以使用以下代码示例:

    DataContext.Groups.FirstOrDefault(item => 
        System.Data.Objects.SqlClient.SqlFunctions.CharIndex(item.Keywords, keyword).Value >=0 && item.IsEnabled)
    

    【讨论】:

      【解决方案3】:

      相反,您可以使用以下方法来降低案例:

      var lowerCaseItem = item.ToLower();
      

      如果您的项目是string 类型。那么这可能会让你度过那个异常。

      【讨论】:

      • 通过使用 string.contains().toLower() 我可以解决这个问题,但 toLower 又是一个重载。 string.indexof 我可以检查大小写。我期待的不是 Contains 方法
      • 我明白了,但我猜你走错了方向。 @MarcinJuraszek 的评论不会起到作用吗?
      • 除了解决这个问题,我最大的疑问是 Inside contains 方法我认为他们正在检查相同的功能索引,那么为什么 entityframework 会抛出异常?
      • “检查相同的功能索引”是什么意思?
      • 如果您深入研究一些 MS 提供的代码,他们会使用 .ToUpper()。我说,对 MS 来说已经足够好了,对我来说已经足够好了。
      【解决方案4】:

      Erik Funkenbush 的答案在将其视为数据库问题时完全有效。但是我觉得如果您想有效地遍历它们,就需要一个更好的结构来保存有关关键字的数据。

      请注意,此答案并不是为了更好,它旨在解决您的数据模型中的问题,而不是使环境适应当前(显然有缺陷,因为存在问题)您拥有的数据模型。

      无论时间限制如何(我意识到这不是最简单的解决方法),我的主要建议是为关键字添加一个单独的表(与其相关类具有多对多关系)。

      [GROUPS] * ------- * [KEYWORD]
      

      这应该允许您搜索关键字,并且只有 然后 检索与该关键字相关的项目(基于 ID 而不是复合字符串)。

      int? keywordID = DataContext.Keywords.Where(x => x.Name == keywordFilter).Select(x => x.Id).FirstOrDefault();
      
      if(keywordID != null)
      {
          getGroup = DataContext.Groups.FirstOrDefault(group => group.Keywords.Any(kw => kw.Id == keywordID));
      }
      

      但如果在当前项目中不再可能进行此类修复,我完全可以理解。不过我想提一下,以防将来有人偶然发现这个问题并且仍然可以选择改进数据结构。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-25
        • 1970-01-01
        • 2015-09-20
        • 2015-07-20
        • 2020-01-26
        • 1970-01-01
        • 1970-01-01
        • 2016-06-09
        相关资源
        最近更新 更多