Share via


データベース関数

データベース関数は、データベースで C# のメソッドに相当するものです。 データベース関数は 0 個以上のパラメーターを使用して呼び出すことができ、パラメーターの値に基づいて結果が計算されます。 クエリに SQL を使用するほとんどのデータベースにより、データベース関数がサポートされています。 そのため、EF Core のクエリ変換によって生成される SQL でも、データベース関数を呼び出すことができます。 C# のメソッドを、EF Core のデータベース関数に厳密に変換する必要はありません。

  • C# のメソッドには同等のデータベース関数がない場合があります。
    • String.IsNullOrEmpty メソッドは、null チェックと、関数ではなくデータベース内の空の文字列との比較に変換されます。
    • 文字列比較はデータベースでは表現できないか、簡単に模倣できないため、String.Equals(String, StringComparison) メソッドと同等のものはデータベースにはありません。
  • データベース関数には、それに相当する C# メソッドがない場合があります。 メソッドを持たない C# の ?? 演算子は、データベースの COALESCE 関数に変換されます。

データベース関数の種類

EF Core の SQL 生成でサポートされているのは、データベースで使用できる関数のサブセットです。 この制限は、特定のデータベース関数を LINQ のクエリで表す機能に由来します。 さらに、データベース関数のサポートはデータベースごとに異なるため、EF Core により共通のサブセットが提供されています。 データベース プロバイダーは、EF Core の SQL 生成を自由に拡張して、より多くのパターンをサポートできます。 EF Core によってサポートされて個別に識別されるデータベース関数の種類を次に示します。 これらの用語は、EF Core プロバイダーによって組み込まれている変換を理解するのにも役立ちます。

組み込み関数とユーザー定義関数

組み込み関数はデータベースであらかじめ定義されていますが、ユーザー定義関数はユーザーによってデータベースで明示的に定義されます。 EF Core によってクエリがデータベース関数を使用するように変換される場合は、その関数をデータベースで常に使用できるように、組み込み関数が使用されます。 データベースによっては、SQL を正しく生成するために組み込み関数を区別する必要があります。 たとえば、SqlServer の場合は、すべてのユーザー定義関数をスキーマ修飾名で呼び出す必要があります。 一方、SqlServer の組み込み関数にはスキーマはありません。 PostgreSQL の場合は、組み込み関数は public スキーマで定義されていますが、スキーマ修飾名を使用して呼び出すことができます。

集計関数とスカラー関数とテーブル値関数

  • スカラー関数は、スカラー値 (整数や文字列など) をパラメーターとして受け取り、結果としてスカラー値を返します。 スカラー関数は、スカラー値を渡すことができる SQL のすべての場所で使用できます。
  • 集計関数は、スカラー値のストリームをパラメーターとして受け取り、結果としてスカラー値を返します。 集計関数は、クエリ結果セット全体または GROUP BY 演算子を適用することによって生成される値のグループに適用されます。
  • テーブル値関数は、スカラー値をパラメーターとして受け取り、結果として行のストリームを返します。 テーブル値関数は、FROM 句のテーブル ソースとして使用されます。

ニラディック関数

ニラディック関数は、パラメーターを持たず、かっこを使用せずに呼び出す必要がある、特別なデータベース関数です。 それらは、C# のインスタンスでのプロパティやフィールドのアクセスに似ています。 ニラディック関数は、空のかっこが必要なパラメーターなし関数とは異なるものです。 常にかっこが必要なデータベース関数には、特別な名前はありません。 パラメーターの数に基づくデータベース関数のもう 1 つのサブセットは、可変個引数関数です。 可変個引数関数は、呼び出されるときに、異なる数のパラメーターを受け取ることができます。

EF Core でのデータベース関数のマッピング

EF Core では、C# 関数とデータベース関数の間のマッピングに 3 つの異なる方法がサポートされています。

組み込み関数のマッピング

既定では、EF Core プロバイダーが、プリミティブ型に対するさまざまな組み込み関数のマッピングを提供します。 たとえば、SqlServer では String.ToLower()LOWER に変換されます。 この機能により、ユーザーは LINQ でシームレスにクエリを作成できます。 通常は、クライアント側で C# 関数によって提供されるものと同じ結果を提供する変換が、データベースに用意されています。 それを実現するための実際の変換が、データベース関数より複雑になることがあります。 シナリオによっては、C# の一致するセマンティクスではなく、最も適切な変換が提供されることもあります。 また、同じ機能を使用して、一部の C# メンバー アクセスに共通の変換を提供することもできます。 たとえば、SqlServer では String.LengthLEN に変換されます。 プロバイダーとは別に、プラグイン ライターも変換を追加できます。 この拡張性は、プラグインによってプリミティブ型としてさらに多くの型のサポートが追加され、それらに対してメソッドを変換する必要がある場合に便利です。

EF.Functions のマッピング

すべてのデータベース関数に同等の C# 関数があるわけではないため、EF Core プロバイダーには特定のデータベース関数を呼び出すための特別な C# メソッドがあります。 これらのメソッドは、LINQ クエリで使用される EF.Functions への拡張メソッドとして定義されています。 これらのメソッドは、特定のデータベース関数と密接に関連付けられているため、プロバイダー固有です。 そのため、あるプロバイダーで動作するメソッドが、他のプロバイダーでは機能しない可能性があります。 さらに、これらのメソッドの目的は、変換されたクエリでデータベース関数を呼び出すことであるため、クライアントでそれらを評価しようとすると例外になります。

ユーザー定義関数のマッピング

EF Core プロバイダーによって提供されるマッピングとは別に、ユーザーがカスタム マッピングを定義することもできます。 ユーザー定義のマッピングを使用すると、ユーザーのニーズに応じてクエリの変換を拡張できます。 この機能は、ユーザーが LINQ クエリから呼び出したいユーザー定義関数がデータベースに存在する場合に便利です。

関連項目