カスタム データベース関数を呼び出す方法 (LINQ to Entities)

ここでは、データベースで定義されたカスタム関数を 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 クエリからメソッドを呼び出します。

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

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

Dd456847.note(ja-jp,VS.100).gif注 :
カスタム データベース関数を呼び出す手順は、データベース サーバーとは無関係にすべて同じです。ただし、下に示すコードは、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

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

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

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

<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
[EdmFunction("SchoolModel.Store", "AvgStudentGrade")]
public static decimal? AvgStudentGrade(int studentId)
{
    throw new NotSupportedException("Direct calls are not supported.");
}

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

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
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);
    }
}

参照

概念

LINQ to Entities でのクエリ

その他のリソース

.edmx File Overview