【问题标题】:Case-Insensitive String Comparison not working in C#?不区分大小写的字符串比较在 C# 中不起作用?
【发布时间】:2013-10-26 03:49:41
【问题描述】:

根据这个问题的答案:

How can I do a case insensitive string comparison?

我正在尝试不使用 Compare 或 ToLower 进行不区分大小写的比较:

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

但是我得到一个错误:

为调用“Boolean”方法提供的参数数量不正确 等于(System.String, System.String, System.StringComparison)'

我做错了什么?

【问题讨论】:

  • 您是否验证过 username 和 s.Username 是字符串类型。
  • 很确定 L2S 不支持该特定方法。如果这是实际可执行的 C# 代码,而不是由查询提供程序翻译的内容,那就没问题了。
  • 你为什么要避免使用 string.Compare?

标签: c# asp.net linq linq-to-sql


【解决方案1】:

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

在 Linq-to-Sql 中你应该可以使用SqlMethods.Like(s.UserName, userName),像这样:

var user = db.Users.FirstOrDefault(s => SqlMethods.Like(s.UserName, userName));

SqlMethods 位于 System.Data.Linq.SqlClient 命名空间中。

Like 方法不区分大小写,因此您应该得到预期的结果。

编辑:我尝试得到“LINQ to Entities 无法识别方法Boolean Like(System.String, System.String) 方法,并且此方法无法转换为商店表达式。”

这似乎是 EF (link) 的一个已知问题。

这对我有用:

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

看起来,虽然 EF 很难将静态 Equals 转换为 SQL,但它在转换实例 Equals 时没有问题。这是一个非常好的发现 - 它提供了一个易于阅读、高性能的解决方案。

您还可以对ToUpperCaseToLowerCase 使用更简单的方法,但这可能会阻止查询优化器使用索引:

// Warning: this may not perform well.
var user = db.Users.FirstOrDefault(s => s.UserName.ToUpperCase() == userName.ToUpperCase());

【讨论】:

  • 谢谢。我尝试得到“LINQ to Entities 无法识别方法 'Boolean Like(System.String, System.String)' 方法,并且此方法无法转换为存储表达式。” - 想法?
  • 这对我有用:db.Users.FirstOrDefault(s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase));我不知道在选择答案方面该怎么做 - 请随时记下这一点,我可以检查你的答案?
  • 你会说我在评论中发布的解决方案有什么问题吗?我一直在寻找一个遵循最佳实践的简单、高性能的解决方案。
  • @SB2055 你的解决方案是最好的:EF翻译静态Equals有问题有点奇怪,但是把实例Equals很好,但是由于这两个函数是分开处理的,一个会工作而另一个会失败是有道理的。
猜你喜欢
  • 2021-05-09
  • 1970-01-01
  • 2012-02-29
  • 2014-06-20
  • 1970-01-01
  • 2011-05-27
  • 2015-07-23
相关资源
最近更新 更多