Dela via


Så här anropar du anpassade databasfunktioner

Det här avsnittet beskriver hur du anropar anpassade funktioner som definieras i databasen från LINQ till entitetsfrågor.

Databasfunktioner som anropas från LINQ till entitetsfrågor körs i databasen. Körning av funktioner i databasen kan förbättra programmets prestanda.

Proceduren nedan innehåller en övergripande disposition för att anropa en anpassad databasfunktion. Exemplet nedan innehåller mer information om stegen i proceduren.

Anropa anpassade funktioner som har definierats i databasen

  1. Skapa en anpassad funktion i databasen.

    Mer information om hur du skapar anpassade funktioner i SQL Server finns i CREATE FUNCTION (Transact-SQL).

  2. Deklarera en funktion i lagringsschemats definitionsspråk (SSDL) för .edmx-filen. Namnet på funktionen måste vara samma som namnet på funktionen som deklareras i databasen.

    Mer information finns i Funktionselement (SSDL).

  3. Lägg till en motsvarande metod i en klass i programkoden och tillämpa en EdmFunctionAttribute på metoden Observera att NamespaceName attributets parametrar och FunctionName är namnområdesnamnet för den konceptuella modellen respektive funktionsnamnet i den konceptuella modellen. Funktionsnamnmatchning för LINQ är skiftlägeskänslig.

  4. Anropa metoden i en LINQ till entitetsfråga.

Exempel 1

I följande exempel visas hur du anropar en anpassad databasfunktion från en LINQ till entitetsfråga. I exemplet används skolmodellen. Information om skolmodellen finns i Skapa skolexempeldatabasen och generera filen School .edmx.

Följande kod lägger till AvgStudentGrade funktionen i exempeldatabasen School.

Kommentar

Stegen för att anropa en anpassad databasfunktion är desamma oavsett databasserver. Koden nedan är dock specifik för att skapa en funktion i en SQL Server-databas. Koden för att skapa en anpassad funktion på andra databasservrar kan skilja sig åt.

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

Exempel 2

Deklarera sedan en funktion i lagringsschemats definitionsspråk (SSDL) för . edmx-filen . Följande kod deklarerar AvgStudentGrade funktionen i SSDL:

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

Exempel 3

Skapa nu en metod och mappa den till funktionen som deklareras i SSDL. Metoden i följande klass mappas till funktionen som definierats i SSDL (ovan) med hjälp av en EdmFunctionAttribute. När den här metoden anropas körs motsvarande funktion i databasen.

[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

Exempel 4

Anropa slutligen metoden i en LINQ till entitetsfråga. Följande kod visar elevernas efternamn och genomsnittliga betyg i konsolen:

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

Se även