16

根据对这个问题的回答:

如何进行不区分大小写的字符串比较?

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

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

但是我收到一个错误:

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

我究竟做错了什么?

4

1 回答 1

38

字符串比较与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(链接)的一个已知问题。

这对我有用:

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

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

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

// Warning: this may not perform well.
var user = db.Users.FirstOrDefault(s => s.UserName.ToUpperCase() == userName.ToUpperCase());
于 2013-10-26T03:56:12.553 回答