LINQ Где игнорировать акцентуацию и регистр - PullRequest
24 голосов
/ 14 сентября 2011

Какой самый простой способ фильтрации элементов с помощью LINQ с помощью метода Where, игнорирующий акцентуацию и регистр?

До сих пор я мог игнорировать Casing, вызывая методы для свойств, что я не считаю хорошей идеей, поскольку он вызывает один и тот же метод для каждого элемента (верно?).

Итак, вот что я получил:

var result = from p in People
             where p.Name.ToUpper().Contains(filter.ToUpper())
             select p;

Пожалуйста, скажите мне, если это хорошая практика и самый простой способ игнорировать акцентуацию.

Ответы [ 4 ]

45 голосов
/ 16 ноября 2011

Чтобы игнорировать регистр и акценты (диакритические знаки), вы можете сначала определить метод расширения следующим образом:

    public static string RemoveDiacritics(this String s)
    {
        String normalizedString = s.Normalize(NormalizationForm.FormD);
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < normalizedString.Length; i++)
        {
            Char c = normalizedString[i];
            if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                stringBuilder.Append(c);
        }

        return stringBuilder.ToString();
    }

(Изменено с Игнорирование акцентированных букв при сравнении строк )

Теперь вы можете выполнить свой запрос:

string queryText = filter.ToUpper().RemoveDiacritics();

var result = from p in People
         where p.Name.ToUpper().RemoveDiacritics() == queryText
         select p;

Это хорошо, если вы просто перебираете коллекцию в C #, но если вы используете LINQ to SQL, предпочтительно избегать нестандартных методов (включая методы расширения) в вашем запросе LINQ.Это потому, что ваш код не может быть преобразован в допустимый SQL и, следовательно, запущен на SQL Server со всей его прекрасной оптимизацией производительности.

Поскольку, похоже, не существует стандартного способа игнорировать акценты в LINQ to SQL, вВ этом случае я бы предложил изменить тип поля, в котором вы хотите искать, чтобы он не зависел от регистра и акцента (CI_AI).

В вашем примере:

ALTER TABLE People ALTER COLUMN Name [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AI

Ваш запрос теперь должен игнорироватьсяакцентуация и регистр.

Обратите внимание, что вам нужно будет временно удалить все уникальные ограничения на поле до выполнения вышеуказанного запроса, например,

ALTER TABLE People DROP CONSTRAINT UQ_People_Name

Теперь ваш запрос LINQбудет просто:

var result = from p in People
         where p.Name == filter
         select p;

См. связанный вопрос здесь .

1 голос
/ 19 декабря 2014

Изменить параметры сортировки:

ALTER TABLE dbo.MyTable 
ALTER COLUMN CharCol varchar(10)**COLLATE Latin1_General_CI_AS** NOT NULL;
0 голосов
/ 14 марта 2018

Следуя решению Dunc об изменении параметров сортировки всей базы данных, вот полный учебник, посвященный индексам, ключам и т. Д.:

https://www.codeproject.com/Articles/302405/The-Easy-way-of-changing-Collation-of-all-Database

(Только сначала прочитайте все комментарии.)

0 голосов
/ 14 сентября 2011

Вот некоторый код, который позволяет сравнивать, игнорируя акцентуацию:

Игнорирование акцентированных букв при сравнении строк

У меня будет порядочность не копировать код, поэтомуАвтор может получить репутацию за свой ответ.Теперь, отвечая на ваш вопрос:

Вы получите этот кусок кода и будете использовать его так:

var result = from p in People
             where p.Name.ToUpper().Contains(RemoveDiacritics(filter.ToUpper()))
             select p;

Вы даже превратите этот код в метод расширения.У меня есть:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...