方法: カスタム データベース関数を呼び出す

ここでは、データベースで定義されたカスタム関数を LINQ Entities クエリから呼び出す方法について説明します。

LINQ to Entities クエリから呼び出されるデータベース関数は、データベース内で実行されます。 データベース内で関数を実行すると、アプリケーションのパフォーマンスが向上します。

下に示す手順は、カスタム データベース関数を呼び出す方法の概要をまとめたものです。 各手順の詳しい説明は、その後の例で示します。

データベースで定義されるカスタム関数を呼び出すには

  1. データベースにカスタム関数を作成します。

    SQL Server でカスタム関数を作成する方法の詳細については、「CREATE FUNCTION (Transact-SQL)」を参照してください。

  2. 関数を .edmx ファイルのストア スキーマ定義言語 (SSDL) で宣言します。 関数の名前は、データベースで宣言される関数と同じ名前にする必要があります。

    詳しくは、「Function 要素 (SSDL)」をご覧ください。

  3. 対応するメソッドをアプリケーション コードのクラスに追加して、EdmFunctionAttribute をそのメソッドに適用する必要があります。属性の NamespaceName パラメーターと FunctionName パラメーターが、それぞれ概念モデルの名前空間名と概念モデルの関数名であることに注意してください。 LINQ の関数名解決では、大文字と小文字が区別されます。

  4. LINQ to Entities クエリからメソッドを呼び出します。

例 1

次の例は、カスタム データベース関数を LINQ to Entities クエリから呼び出す方法について説明します。 この例では、School モデルを使用します。 School モデルの詳細については、「School サンプル データベースの作成」と「School .edmx ファイルの生成」を参照してください。

次のコードは、AvgStudentGrade 関数を School のサンプル データベースに追加しています。

Note

カスタム データベース関数を呼び出す手順は、データベース サーバーとは無関係にすべて同じです。 ただし、下に示すコードは、SQL Server データベースで関数を作成する方法に固有のものです。 他のデータベース サーバーでカスタム関数を作成する場合には、コードは異なることがあります。

USE [School]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[AvgStudentGrade](@studentId INT)
RETURNS DECIMAL(3,2)
AS
    BEGIN
    DECLARE @avg DECIMAL(3,2);
    SELECT @avg = avg(Grade) FROM StudentGrade WHERE StudentID = @studentId;

    RETURN @avg;
END

例 2

次に、関数を .edmx ファイルのストア スキーマ定義言語 (SSDL) で宣言します。 次のコードでは、AvgStudentGrade 関数が SSDL で宣言されています。

<Function Name="AvgStudentGrade" ReturnType="decimal" Schema="dbo" >
  <Parameter Name="studentId" Mode="In" Type="int" />
</Function>

例 3

次に、メソッドを作成して、SSDL で宣言された関数にマップします。 次のクラスのメソッドは、EdmFunctionAttribute を使用して SSDL (上を参照) で定義される関数にマップされます。 このメソッドが呼び出されると、データベース内の対応する関数が実行されます。

[EdmFunction("SchoolModel.Store", "AvgStudentGrade")]
public static decimal? AvgStudentGrade(int studentId)
{
    throw new NotSupportedException("Direct calls are not supported.");
}
<EdmFunction("SchoolModel.Store", "AvgStudentGrade")>
Public Function AvgStudentGrade(ByVal studentId As Integer) _
    As Nullable(Of Decimal)
    Throw New NotSupportedException("Direct calls are not supported.")
End Function

例 4

最後に、メソッドを LINQ to Entities クエリで呼び出します。 次のコードは、学生の姓と平均の成績をコンソールに表示します。

using (SchoolEntities context = new SchoolEntities())
{
    var students = from s in context.People
                   where s.EnrollmentDate != null
                   select new
                   {
                       name = s.LastName,
                       avgGrade = AvgStudentGrade(s.PersonID)
                   };

    foreach (var student in students)
    {
        Console.WriteLine("{0}: {1}", student.name, student.avgGrade);
    }
}
Using context As New SchoolEntities()
    Dim students = From s In context.People _
                   Where s.EnrollmentDate IsNot Nothing _
                   Select New With {.name = s.LastName, _
                                   .avgGrade = AvgStudentGrade(s.PersonID)}

    For Each student In students
        Console.WriteLine("{0}: {1}", _
                            student.name, _
                            student.avgGrade)
    Next
End Using

関連項目