Параметры сортировки и учет регистра

Примечание

Эта возможность появилась в EF Core 5.0.

Обработка текста в базах данных может быть сложной и требует больше внимания пользователей, чем подозрительная. В одном случае базы данных значительно зависят от того, как они обрабатывали текст; например, хотя в некоторых базах данных учитывается регистр по умолчанию (например, Sqlite, PostgreSQL), другие не учитывают регистр (SQL Server, MySQL). Кроме того, в связи с использованием индексов, чувствительность к регистру и аналогичные аспекты могут иметь более далекое влияние на производительность запросов: в то время как в этом случае может возникнуть желание использовать string.ToLower для принудительного сравнения без учета регистра в базе данных с учетом регистра, это может помешать приложению использовать индексы. На этой странице подробно описано, как настроить чувствительность к регистру или, как правило, параметры сортировки, а также как это сделать с помощью эффективного способа, не нарушая производительность запросов.

Общие сведения о параметрах сортировки

Фундаментальным понятием обработки текста является Сортировка, которая представляет собой набор правил, определяющих порядок упорядочения текстовых значений и их сравнение на равенство. Например, хотя параметры сортировки без учета регистра не учитывают различия между буквами верхнего и нижнего регистра в целях сравнения на равенство, параметры сортировки с учетом регистра не применяются. Однако, так как учет регистра учитывает язык и региональные параметры (например i , и I представляет другую букву в турецком языке), существует несколько параметров сортировки без учета регистра, каждый из которых имеет собственный набор правил. Область применения параметров сортировки также выходит за рамки учета регистра и других аспектов символьных данных. Например, на немецком языке он иногда (но не всегда) желательно рассматривать ä и ae как идентичный. Наконец, параметры сортировки также определяют порядок упорядочения текстовых значений: а немецкая äa в конце алфавита.

Все текстовые операции в базе данных используют параметры сортировки — независимо от того, следует ли явно или неявно определить, как операция сравнивает строки и упорядочивает их. Реальный список доступных параметров сортировки и их схем именования зависит от базы данных. в разделе ниже приведены ссылки на соответствующие страницы документации по различным базам данных. К счастью, база данных обычно позволяет определять параметры сортировки по умолчанию на уровне базы данных или столбца, а также явно указывать, какие параметры сортировки следует использовать для конкретных операций в запросе.

Параметры сортировки баз данных

В большинстве систем баз данных параметры сортировки по умолчанию определяются на уровне базы данных. Если не переопределено, то эти параметры сортировки неявно применяются ко всем текстовым операциям, происходящим в этой базе данных. Параметры сортировки базы данных обычно задаются во время создания базы данных (с помощью CREATE DATABASE инструкции DDL), а если не задано, по умолчанию устанавливается какое-либо значение уровня сервера, определенное во время установки. например, параметры сортировки уровня сервера по умолчанию в SQL Server — это SQL_Latin1_General_CP1_CI_AS , без учета регистра, параметры сортировки с учетом диакритических знаков. Хотя системы баз данных, как правило, позволяют изменять параметры сортировки существующей базы данных, это может привести к осложнениям. рекомендуется выбрать параметры сортировки перед созданием базы данных.

при использовании EF Core миграции для управления схемой базы данных в OnModelCreating методе модели настраивается база данных SQL Server для использования параметров сортировки с учетом регистра.

modelBuilder.UseCollation("SQL_Latin1_General_CP1_CS_AS");

Параметры сортировки столбца

Параметры сортировки также могут быть определены для текстовых столбцов, переопределяя значения по умолчанию для базы данных. Это может быть полезно, если в некоторых столбцах необходимо учитывать регистр, а остальная часть базы данных должна учитывать регистр.

При использовании EF Core миграций для управления схемой базы данных Следующая настройка столбца для Name свойства не учитывает регистр в базе данных, которая в противном случае настроена с учетом регистра:

modelBuilder.Entity<Customer>().Property(c => c.Name)
    .UseCollation("SQL_Latin1_General_CP1_CI_AS");

Явные параметры сортировки в запросе

В некоторых случаях один и тот же столбец необходимо запрашивать с использованием различных параметров сортировки в разных запросах. Например, одному запросу может потребоваться выполнить сравнение столбца с учетом регистра, в то время как другой может потребоваться сравнение с тем же столбцом без учета регистра. Это можно сделать, явно указав параметры сортировки в самом запросе:

var customers = context.Customers
    .Where(c => EF.Functions.Collate(c.Name, "SQL_Latin1_General_CP1_CS_AS") == "John")
    .ToList();

при этом создается COLLATE предложение в SQL запросе, в котором применяются параметры сортировки с учетом регистра, независимо от параметров сортировки, определенных на уровне столбца или базы данных.

SELECT [c].[Id], [c].[Name]
FROM [Customers] AS [c]
WHERE [c].[Name] COLLATE SQL_Latin1_General_CP1_CS_AS = N'John'

Явные параметры сортировки и индексы

Индексы являются одним из наиболее важных факторов производительности базы данных — запрос, который эффективно работает с индексом, может привести к остановке без этого индекса. Индексы неявно наследуют параметры сортировки своего столбца; Это означает, что все запросы к столбцу автоматически подходят для использования индексов, определенных в этом столбце, при условии, что в запросе не указаны другие параметры сортировки. Явное указание параметров сортировки в запросе не позволит этому запросу использовать индекс, определенный для этого столбца, так как параметры сортировки больше не совпадают. Поэтому рекомендуется соблюдать осторожность при использовании этой функции. Всегда предпочтительнее определить параметры сортировки на уровне столбца (или базы данных), что позволяет всем запросам неявно использовать эти параметры сортировки и преимущества любого индекса.

Обратите внимание, что некоторые базы данных позволяют определять параметры сортировки при создании индекса (например, PostgreSQL, SQLite). Это позволяет определять несколько индексов в одном столбце, ускоряя операции с различными параметрами сортировки (например, сравнение с учетом регистра и без учета регистра). Дополнительные сведения см. в документации поставщика базы данных.

Предупреждение

Всегда проверяйте планы запросов запросов и убедитесь, что в критически важных для производительности запросах используются правильные индексы, выполняемые на больших объемах данных. Переопределение чувствительности к регистру в запросе с помощью EF.Functions.Collate (или путем вызова string.ToLower ) может оказать значительное влияние на производительность приложения.

Перевод встроенных строковых операций .NET

В .NET равенство по строкам учитывает регистр по умолчанию: s1 == s2 выполняет порядковое сравнение, которое требует идентичности строк. поскольку параметры сортировки баз данных по умолчанию могут различаться, и, поскольку для использования индексов желательно простое равенство, EF Core не пытается преобразовать простое равенство в базу данных с учетом регистра: равенство в C# преобразуется непосредственно в SQL равенство, которое может или не учитывать регистр, в зависимости от используемой базы данных и ее конфигурации параметров сортировки.

Кроме того, .NET предоставляет перегрузки для string.Equals принятия StringComparison перечисления, что позволяет указывать чувствительность к регистру и культуру для сравнения. по разработке EF Core отменяет перевод этих перегрузок в SQL и попытку их использования приведет к возникновению исключения. В одном случае EF Core не знает, какие параметры сортировки с учетом регистра или без учета регистра следует использовать. Что более важно, применение параметров сортировки в большинстве случаев предотвращает использование индексов, значительно влияя на производительность для очень простой и часто используемой конструкции .NET. Чтобы принудительно использовать сравнение с учетом регистра или без учета регистра, укажите параметры сортировки явно с помощью, EF.Functions.Collate как описано выше.

Дополнительные ресурсы

Сведения, относящиеся к базе данных

Другие ресурсы

  • EF Core Community сеансе Standup, в котором приводятся параметры сортировки и изучаются аспекты производительности и индексирования.