如何:呼叫自訂資料庫函式
本主題描述如何呼叫資料庫中定義的自訂資料庫函式,而資料庫是來自 LINQ to Entities 查詢。
從 LINQ to Entities 查詢呼叫的資料庫函式會在資料庫中執行。 在資料庫中執行函式可提升應用程式效能。
以下程序提供關於呼叫自訂資料庫函式的重要概述。 程序後的範例提供程序中之步驟相關詳細資訊。
呼叫在資料庫中定義的自訂函式
在您的資料庫中建立自訂函式。
如需在 SQL Server 中建立自訂函式的詳細資訊,請參閱 CREATE FUNCTION (Transact-SQL)。
在 .edmx 檔案的存放結構定義語言 (SSDL) 中宣告函式。 函式的名稱必須和資料庫中宣告的函式名稱一樣。
如需詳細資訊,請參閱函式元素 (SSDL)。
將對應的方法加入至應用程式程式碼的類別中,然後將 EdmFunctionAttribute 套用至方法。請注意,屬性的 NamespaceName 和 FunctionName 參數分別是概念模型的命名空間名稱和概念模型中的函式名稱。 LINQ 的函式名稱解析是區分大小寫的。
呼叫 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