如何:呼叫自訂資料庫函式

本主題描述如何呼叫資料庫中定義的自訂資料庫函式,而資料庫是來自 LINQ to Entities 查詢。

從 LINQ to Entities 查詢呼叫的資料庫函式會在資料庫中執行。 在資料庫中執行函式可提升應用程式效能。

以下程序提供關於呼叫自訂資料庫函式的重要概述。 程序後的範例提供程序中之步驟相關詳細資訊。

呼叫在資料庫中定義的自訂函式

  1. 在您的資料庫中建立自訂函式。

    如需在 SQL Server 中建立自訂函式的詳細資訊,請參閱 CREATE FUNCTION (Transact-SQL)

  2. 在 .edmx 檔案的存放結構定義語言 (SSDL) 中宣告函式。 函式的名稱必須和資料庫中宣告的函式名稱一樣。

    如需詳細資訊,請參閱函式元素 (SSDL)

  3. 將對應的方法加入至應用程式程式碼的類別中,然後將 EdmFunctionAttribute 套用至方法。請注意,屬性的 NamespaceNameFunctionName 參數分別是概念模型的命名空間名稱和概念模型中的函式名稱。 LINQ 的函式名稱解析是區分大小寫的。

  4. 呼叫 LINQ to Entities 查詢中的方法。

範例 1

下列範例示範如何從 LINQ to Entities 查詢中呼叫自訂資料庫函式。 範例使用 School 模型。 如需學校模型的相關資訊,請參閱建立學校範例資料庫產生學校 .edmx 檔案

下列程式碼會將 AvgStudentGrade 函式加入至 School 範例資料庫。

注意

無論資料庫伺服器為何,呼叫自訂資料庫函式的步驟都一樣。 不過,下列程式碼是專門在 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) 中宣告函式。 下列程式碼在 SSDL 中宣告 AvgStudentGrade 函式:

<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

另請參閱