【问题标题】:String.Equals() not working as intendedString.Equals() 没有按预期工作
【发布时间】:2017-06-26 22:45:44
【问题描述】:

我正在使用 LINQ 搜索我的一个实体框架表并根据名称找到一个“组”。该名称是一个字符串,并且似乎是 Unicode(说它在 edmx 中)。我有一个方法GetGroup() 并传入一个名称进行搜索。通过代码进行调试,我的数据库中已经有一个名为“Test”的组。一旦我传入一个名为“TEST”的组,我希望它返回已经在数据库中的“Test”。由于某种原因,它没有找到“测试”并认为“测试”不存在。这是我的查询,我看不出它为什么不起作用。请帮忙。

“name”是传入的组名。我的.Equals 似乎只有在gr.Name 和名称完全相同的情况下才有效。如果一个字符在两个字符串之一中是大写的,则 .Equals 不起作用。我曾尝试使用InvariantCultureIgnoreCase,但这似乎没有帮助。如果有人问,MyLeagueIdLeagueId 将始终匹配,数据库已设置,因此可以有一个不同联赛 ID 的组。我认为这不是问题。

Group g = (from gr in this.DatabaseConnection.Groups
           where gr.Name.Equals(name, StringComparison.OrdinalIgnoreCase) &&
           gr.LeagueId == this.MyLeagueId
           select gr).FirstOrDefault();

【问题讨论】:

  • 你确定一个在结尾/开头没有空格,而另一个没有?
  • 如果Groups表不是太大,那么作为一个测试,你能不能尝试把查询从this.DatabaseConnection.Groups.ToList()中的fr改为...

标签: c# linq entity-framework-4 equals


【解决方案1】:

StringComparison.OrdinalIgnoreCase 的字符串比较在内存中或IEnumerable<T> 中起作用。您正在尝试将它与 IQueryable<T> 一起使用,但您的可查询对象的提供者不理解它。

这对我有用:

db.Users.FirstOrDefault(
     s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase)
);

【讨论】:

  • 静态方法 string.Equals 不起作用,即使使用相同的参数。使用实例方法是解决方案。
  • 我想知道为什么我得到“方法 'Boolean Equals(System.String, System.String, System.StringComparison)' has no supported translation to SQL.”?
【解决方案2】:

使用 LINQ to Entities 时,它会自动将其转换为 LINQ to SQL。如果您正在执行 .Equals 的数据库字段没有 NOCASE(在我的示例中为 SQLite)的整理,那么它将始终区分大小写。换句话说,数据库定义了如何进行字符串比较而不是代码。

【讨论】:

  • 那么有没有办法使用 LINQ to Entities 执行不区分大小写的搜索?
  • 只需让 DB 字段包含整理的 NOCASE(对于 SQLite,在其他 DB 上不确定。我确定它类似)。
  • 我刚刚测试了str1 == str2,它进行了不区分大小写的搜索,所以我不需要Equals 的麻烦。感谢您的意见。
【解决方案3】:

使用String.Compare(),因为它可以翻译成Sql。

Here是一些Linq中字符串匹配的例子,还有Sql翻译。

【讨论】:

  • 这应该是公认的答案。主要是因为很棒的 String Matching in LINQ 链接,它解释得很清楚。
  • 遗憾的是,这在 Oracle 的 ODP.NET 中不起作用,因为 SQL 仍会转换为正常比较。
【解决方案4】:

做了一些研究。你不能这样做。排序规则(比较类型)在表的列级别定义。你不能通过EF修改它。如果它被定义为不区分大小写,那么所有的搜索都将不区分大小写。如果它被定义为区分大小写,那么你唯一的希望就是ToUpper() 字符串。

http://connect.microsoft.com/VisualStudio/feedback/details/435783/entity-framework-conceptual-model-doesnt-support-string-equals-via-linq

http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/3810aa67-f6fe-4624-a14b-eaaa0e05ddcd

EF4 Linq Oracle11g making queries none case-sensitive

LINQ to Entities case sensitive comparison

【讨论】:

  • 没用。我得到了这个异常(不知道为什么......我正在比较的两个对象都是字符串):无法创建类型为“System.StringComparer”的常量值。此上下文仅支持原始类型(“例如 Int32、String 和 Guid”)。
  • @Travyguy9 已更改建议 :-)
  • String.Equals 给了我这个错误(StackTrace 以 LINQ 结尾,所以我认为 LINQ 不喜欢它) - 为调用方法 'Boolean Equals(System.String, System) 提供的参数数量不正确.String, System.StringComparison)'
  • ToUpper/ToLower 工作......我觉得这很愚蠢......不应该为我的 StringComparison 使用 IgnoreCase 为我做这个吗?
  • 不,ToUpper 和 ToLower 是完全不同的野兽。有些字母有问题。小写 ı(它是一个土耳其字符)在转换为大写时等于 I(即欧美 i 的大写)。可能有很多这样的例子。
【解决方案5】:

从技术角度来看,我喜欢 TravyGuy 的回答。 如需更直接、更实用的答案,请尝试使用:

string.Compare(string A, string B, StringComparison.OrdinalIgnoreCase) == 0

【讨论】:

    【解决方案6】:

    试试name.Equals(gr.Name, StringComparison.OrdinalIgnoreCase)

    如果它有效,那么问题可能出在gr.Name

    --- 编辑---

    我猜gr.Name 不是System.string 类型。 (因为String.Equals 给你一个错误==> 从上一篇文章)

    试一试

    (gr.Name as string).Equals(name, StringComparison.OrdinalIgnoreCase)
    

    String.Equals((gr.Name as string), name, StringComparison.OrdinalIgnoreCase)
    

    【讨论】:

      猜你喜欢
      • 2021-10-19
      • 2020-03-18
      • 2012-06-14
      • 2014-11-15
      • 1970-01-01
      • 2012-07-02
      • 2011-09-07
      • 2013-03-03
      • 2015-05-18
      相关资源
      最近更新 更多