根据这个问题的答案:
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提供的参数数量不正确 Equals(System.String,System.String,System.StringComparison)'
我做错了什么?
答案 0 :(得分:33)
与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
没有问题。这是一个非常好的发现 - 它使得易于阅读,高效的解决方案。
您还可以使用更简单的方法ToUpperCase
或ToLowerCase
,但这可能会阻止查询优化器使用索引:
// Warning: this may not perform well.
var user = db.Users.FirstOrDefault(s => s.UserName.ToUpperCase() == userName.ToUpperCase());