Поделиться через


Функции базы данных

Функции базы данных являются эквивалентом методов C# для базы данных. Функцию базы данных можно вызывать без параметров или с несколькими параметрами. Она будет вычислять результат на основе значений параметров. Большинство баз данных, которые для запросов используют SQL, также поддерживают функции базы данных. Итак, SQL, созданный преобразованием запросов EF Core, также позволяет вызывать функции базы данных. Методы C# не должны преобразовывать исключительно в функции базы данных в EF Core.

  • Метод C# может не иметь эквивалентную функцию базы данных.
    • МетодString.IsNullOrEmpty преобразует в проверку значения NULL и сравнение с пустой строкой в базе данных вместо функции.
    • МетодString.Equals(String, StringComparison) не имеет эквивалента в базе данных, поскольку сравнение строк не может быть представлено или легко воспроизведено в базе данных.
  • Функция базы данных может не иметь эквивалентный метод C#. Оператор ?? в C#, который не имеет какого-либо метода, преобразуется в базе данных в функцию COALESCE.

Типы функций базы данных

Создание SQL в EF Core поддерживает подмножество функций, которые можно использовать в базах данных. Это ограничение обусловлено возможностью представления запроса в LINQ для заданной функции базы данных. Кроме того, базы данных имеют разные типы поддержки функций базы данных, поэтому EF Core предоставляет универсальное подмножество. Поставщик базы данных может расширить создание SQL в EF Core, что позволит поддерживать большее количество шаблонов. Ниже приведены типы функций базы данных, которые EF Core поддерживает и уникально идентифицирует. Эти термины также помогают понять, какие преобразования встроены в поставщики EF Core.

Сравнение встроенных и определяемых пользователем функций

Встроенные функции поставляются с базой данных, в то время как определяемые пользователем функции явно определяются пользователем в базе данных. Когда EF Core преобразует запросы для использования функций базы данных, он использует встроенные функции, чтобы обеспечить постоянную доступность функции в базе данных. Для правильного создания SQL в некоторых базах данных необходимо различать встроенные функции. Например, SqlServer требует, чтобы каждую определяемую пользователем функцию вызывали с помощью имени, заданного схемой. В то же время встроенные функции в SqlServer не имеют схемы. PostgreSQL определяет встроенную функцию в схеме public, но ее можно вызывать с помощью имен, заданных схемой.

Сравнение агрегатных, скалярных функций и функций с табличным значением

  • Скалярные функции принимают скалярные значения, например целые числа или строки, в качестве параметров и возвращают скалярное значение в качестве результата. Скалярные функции можно использовать в любом месте в SQL, где можно передавать скалярное значение.
  • Агрегатные функции принимают поток скалярных значений в качестве параметров и возвращают скалярное значение в качестве результата. Агрегатные функции применяются ко всему результирующему набору запроса или к группе значений, созданных при применении оператора GROUP BY.
  • Функции с табличным значением принимают скалярные значения в качестве параметров и возвращают поток строк в качестве результата. Функции с табличным значением используются в качестве источника данных таблицы в предложении FROM.

Нуль-арные функции

Нуль-арные функции — это специальные функции базы данных, которые не имеют параметров и которые следует вызывать без круглых скобок. Они подобны доступу к свойствам и полям в экземпляре C#. Нуль-арные функции отличаются от функций без параметров, поскольку в последних требуются пустые скобки. Для функций базы данных, для которых всегда требуются скобки, не существует специального имени. Другое подмножество функций базы данных, основанное на количестве параметров, — это вариадические функции. Вариадические функции могут принимать разное количество параметров при вызове.

Сопоставления функций базы данных в EF Core

EF Core поддерживает три разных способа сопоставления функций C# и функций базы данных.

Сопоставление встроенных функций

По умолчанию поставщики EF Core предоставляют сопоставления для различных встроенных функций над примитивными типами. Например, String.ToLower() преобразуется в LOWER в SqlServer. Эта функция позволяет пользователям легко создавать запросы в LINQ. Обычно в базе данных предоставляется преобразование, которое дает тот же результат, что и функция C#, что предоставляется на стороне клиента. Иногда, чтобы добиться этого, фактическое преобразование может оказаться более сложным, чем функция базы данных. В некоторых сценариях также предоставляется наиболее подходящее преобразование вместо соответствующей семантики C#. Эта же функция также используется для предоставления общих преобразований для некоторых элементов доступа членов C#. Например, String.Length преобразуется в LEN в SqlServer. Помимо поставщиков, дополнительные преобразования могут также добавлять подключаемые модули записи. Такая расширяемость полезна, когда подключаемые модули добавляют поддержку нескольких типов в качестве примитивных типов и требуют преобразования методов.

Сопоставление EF.Functions

Поскольку не все функции базы данных имеют эквивалентные функции C#, поставщики EF Core имеют специальные методы C# для вызова определенных функций базы данных. Эти методы определяются как методы расширения EF.Functions для использования в запросах LINQ. Эти методы относятся к конкретному поставщику, так как они тесно связаны с конкретными функциями базы данных. Поэтому метод, который работает для одного поставщика, скорее всего, не будет работать для других поставщиков. Кроме того, поскольку цель этих методов заключается в вызове функции базы данных в преобразованном запросе, попытка их вычисления на стороне клиента будет приводить к возникновению исключения.

Сопоставление определяемых пользователем функций

Помимо сопоставлений, предоставляемых поставщиками EF Core, пользователи могут также определять пользовательское сопоставление. Определяемое пользователем сопоставление расширяет преобразование запросов в соответствии с потребностями пользователя. Эта функция полезна, если в базе данных есть определяемые пользователем функции, которые пользователь хочет вызвать из своего запроса LINQ.

См. также