Я читал, что неразумно использовать ToUpper и ToLower для выполнения сравнения строк без учета регистра, но я не вижу альтернативы, когда дело доходит до LINQ-to-SQL. Аргументы ignoreCase и CompareOptions для String.Compare игнорируются LINQ-to-SQL (если вы используете базу данных с учетом регистра, вы получите сравнение с учетом регистра, даже если вы запросите сравнение без учета регистра). ToLower или ToUpper здесь лучший вариант? Одно лучше другого? Я думал, что где-то читал, что ToUpper лучше, но не знаю, применимо ли это здесь. (Я провожу много проверок кода, и все используют ToLower.)
Dim s = From row In context.Table Where String.Compare(row.Name, "test", StringComparison.InvariantCultureIgnoreCase) = 0
Это переводится в SQL-запрос, который просто сравнивает row.Name с «test» и не возвращает «Test» и «TEST» в базе данных с учетом регистра.
LINQQuery.Contains("VaLuE", StringComparer.CurrentCultureIgnoreCase)
иLINQQuery.Except(new string[]{"A VaLUE","AnOTher VaLUE"}, StringComparer.CurrentCultureIgnoreCase)
. Уаху!Ответы:
Как вы говорите, между ToUpper и ToLower есть несколько важных различий, и только одно из них является надежно точным, когда вы пытаетесь выполнять проверки равенства без учета регистра.
В идеале, лучший способ сделать регистронезависимую проверку равенства будет :
String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)
ПРИМЕЧАНИЕ, ОДНАКО это не работает в данном случае! Поэтому мы застряли на
ToUpper
илиToLower
.Обратите внимание на Ordinal IgnoreCase, чтобы сделать его безопасным. Но именно тот тип проверки с учетом регистра, который вы используете, зависит от ваших целей. Но обычно используйте Equals для проверки равенства и Compare при сортировке, а затем выбирайте правильный StringComparison для задания.
Майкл Каплан (признанный авторитет в области культуры и обращения с персонажами, подобного этому) написал соответствующие посты о ToUpper vs. ToLower:
Он говорит: «String.ToUpper - используйте ToUpper, а не ToLower, и укажите InvariantCulture, чтобы подобрать правила корпуса ОС ».
источник
Я использовал
System.Data.Linq.SqlClient.SqlMethods.Like(row.Name, "test")
в своем запросе.Это выполняет сравнение без учета регистра.
источник
SqlClient
.Я пробовал это с помощью лямбда-выражения, и это сработало.
List<MyList>.Any (x => (String.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) && (x.Type == qbType) );
источник
List<>
, что означает, что сравнение происходит в памяти (код C #), а неIQueryable
(илиObjectQuery
), который будет выполнять сравнение в базе данных .Если вы передадите строку без учета регистра в LINQ-to-SQL, она будет передана в SQL без изменений, и сравнение будет происходить в базе данных. Если вы хотите выполнять сравнение строк в базе данных без учета регистра, все, что вам нужно сделать, это создать лямбда-выражение, которое выполняет сравнение, и поставщик LINQ-to-SQL переведет это выражение в SQL-запрос с сохранением вашей строки.
Например, этот запрос LINQ:
from user in Users where user.Email == "foo@bar.com" select user
преобразуется поставщиком LINQ-to-SQL в следующий SQL:
SELECT [t0].[Email] FROM [User] AS [t0] WHERE [t0].[Email] = @p0 -- note that "@p0" is defined as nvarchar(11) -- and is passed my value of "foo@bar.com"
Как видите, строковый параметр будет сравниваться в SQL, что означает, что все должно работать именно так, как вы ожидаете.
источник
Для выполнения запросов Linq to Sql, чувствительных к регистру, объявите «строковые» поля чувствительными к регистру, указав тип данных сервера, используя одно из следующих действий;
varchar(4000) COLLATE SQL_Latin1_General_CP1_CS_AS
или
Примечание. "CS" в приведенных выше типах сопоставления означает "Учитывать регистр".
Его можно ввести в поле «Тип данных сервера» при просмотре свойства с помощью Visual Studio DBML Designer.
Подробнее см. Http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html.
источник
where row.name.StartsWith(q, true, System.Globalization.CultureInfo.CurrentCulture)
источник
Для меня работает следующий двухэтапный подход (VS2010, ASP.NET MVC3, SQL Server 2008, Linq to SQL):
result = entRepos.FindAllEntities() .Where(e => e.EntitySearchText.Contains(item)); if (caseSensitive) { result = result .Where(e => e.EntitySearchText.IndexOf(item, System.StringComparison.CurrentCulture) >= 0); }
источник
!= -1
потому чтоIndexOf
«возвращает -1, если символ или строка не найдены»Иногда значение, хранящееся в базе данных, может содержать пробелы, поэтому запуск может быть неудачным.
String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)
Решение этой проблемы - удалить пробел, затем преобразовать его корпус и выбрать такой
return db.UsersTBs.Where(x => x.title.ToString().ToLower().Replace(" ",string.Empty).Equals(customname.ToLower())).FirstOrDefault();
Обратите внимание в этом случае
customname - это значение, которое соответствует значению базы данных
UsersTBs - это класс
заголовок - столбец базы данных
источник
Помните, что существует разница между тем, работает ли запрос, и тем, насколько он работает эффективно ! Оператор LINQ преобразуется в T-SQL, когда целью оператора является SQL Server, поэтому вам нужно подумать о создаваемом T-SQL.
Использование String.Equals, скорее всего (я предполагаю), вернет все строки из SQL Server, а затем выполнит сравнение в .NET, потому что это выражение .NET, которое нельзя преобразовать в T-SQL.
Другими словами, использование выражения расширит ваш доступ к данным и лишит вас возможности использовать индексы. Он будет работать на небольших столах, и вы не заметите разницы. На большом столе он мог работать очень плохо.
Это одна из проблем, существующих с LINQ; люди больше не думают о том, как будут выполняться написанные ими утверждения.
В этом случае нет способа делать то, что вы хотите, без использования выражения - даже в T-SQL. Поэтому, возможно, вы не сможете сделать это более эффективно. Даже приведенный выше ответ T-SQL (с использованием переменных с сопоставлением), скорее всего, приведет к игнорированию индексов, но если это большая таблица, стоит запустить инструкцию и посмотреть план выполнения, чтобы узнать, использовался ли индекс. .
источник