Ответ 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
нечувствителен к регистру, поэтому вы должны получить ожидаемый результат.
EDIT: Я попытался и получил "LINQ to Entities не распознает метод
Boolean Like(System.String, System.String)
, и этот метод не может быть переведен в выражение хранилища".
Это, по-видимому, известная проблема с EF (ссылка).
Это работает для меня:
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());