Share via


Postupy: Volání vlastních databázových funkcí

Toto téma popisuje, jak volat vlastní funkce definované v databázi z dotazů LINQ to Entities.

Databázové funkce, které jsou volány z LINQ to Entities dotazy se spouští v databázi. Provádění funkcí v databázi může zlepšit výkon aplikace.

Následující postup poskytuje základní přehled pro volání vlastní databázové funkce. Následující příklad obsahuje podrobnější informace o krocích v postupu.

Volání vlastních funkcí definovaných v databázi

  1. Vytvořte ve své databázi vlastní funkci.

    Další informace o vytváření vlastních funkcí na SQL Serveru naleznete v tématu CREATE FUNCTION (Transact-SQL).

  2. Deklarujte funkci v jazyce definice schématu úložiště (SSDL) vašeho souboru .edmx. Název funkce musí být stejný jako název funkce deklarované v databázi.

    Další informace najdete v tématu Element funkce (SSDL).a0>

  3. Přidejte odpovídající metodu do třídy v kódu aplikace a použijte metodu EdmFunctionAttribute Poznámka: NamespaceName A FunctionName parametry atributu jsou název oboru názvů konceptuálního modelu a název funkce v koncepčním modelu v uvedeném pořadí. Rozlišení názvů funkcí pro LINQ rozlišují malá a velká písmena.

  4. Volání metody v dotazu LINQ to Entities.

Příklad 1

Následující příklad ukazuje, jak volat vlastní databázovou funkci z dotazu LINQ to Entities. V příkladu se používá školní model. Informace o školním modelu naleznete v tématu Vytvoření ukázkové databáze školy a generování souboru School .edmx.

Následující kód přidá AvgStudentGrade funkci do ukázkové databáze School.

Poznámka:

Postup volání vlastní databázové funkce je stejný bez ohledu na databázový server. Následující kód je však specifický pro vytvoření funkce v databázi SQL Serveru. Kód pro vytvoření vlastní funkce na jiných databázových serverech se může lišit.

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

Příklad 2

Dále deklarujte funkci v jazyce SSDL (Store Schema Definition Language) vašeho souboru .edmx . Následující kód deklaruje AvgStudentGrade funkci v SSDL:

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

Příklad 3

Teď vytvořte metodu a namapujte ji na funkci deklarovanou v SSDL. Metoda v následující třídě je mapována na funkci definovanou v SSDL (výše) pomocí .EdmFunctionAttribute Při zavolání této metody se spustí odpovídající funkce v databázi.

[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

Příklad 4

Nakonec zavolejte metodu v dotazu LINQ to Entities. V následujícím kódu se zobrazí příjmení studentů a průměrné známky v konzole:

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

Viz také