Partager via


Comment : appeler des fonctions de base de données personnalisées

Cette rubrique décrit comment appeler des fonctions personnalisées définies dans la base de données dans des requêtes LINQ to Entities.

Les fonctions de base de données qui sont appelées à partir de requêtes LINQ to Entities sont exécutées dans la base de données. L'exécution de fonctions dans la base de données peut améliorer les performances de l'application.

La procédure ci-dessous fournit un plan de haut niveau pour l'appel d'une fonction de base de données personnalisée. L'exemple qui suit fournit plus de détails sur les étapes de la procédure.

Pour appeler des fonctions personnalisées définies dans la base de données

  1. Créez une fonction personnalisée dans votre base de données.

    Pour plus d’informations sur la création de fonctions personnalisées dans SQL Server, consultez CREATE FUNCTION (Transact-SQL).

  2. Déclarez une fonction dans la partie SSDL (Store Schema Definition Language) de votre fichier .edmx. Le nom de la fonction doit être le même que le nom de la fonction déclarée dans la base de données.

    Pour plus d’informations, consultez Function (élément) (SSDL).

  3. Ajoutez une méthode correspondante à une classe dans votre code d'application et appliquez un attribut EdmFunctionAttribute à la méthode. Notez que les paramètres NamespaceName et FunctionName de l'attribut sont respectivement le nom de l'espace de noms du modèle conceptuel et le nom de la fonction dans le modèle conceptuel. La résolution des noms de fonctions pour LINQ respecte la casse.

  4. Appelez la méthode dans une requête LINQ to Entities.

Exemple 1

L'exemple suivant montre comment appeler une fonction de base de données personnalisée dans une requête LINQ to Entities. L'exemple utilise le modèle School. Pour plus d’informations sur le modèle School, consultez Création de l’exemple de base de données School et Génération du fichier School .edmx.

Le code suivant ajoute la fonction AvgStudentGrade à l'exemple de base de données School.

Notes

La procédure d'appel d'une fonction de base de données personnalisée est la même indépendamment du serveur de base de données. Toutefois, le code ci-dessous est spécifique à la création d'une fonction dans une base de données SQL Server. Le code pour la création d'une fonction personnalisée sur d'autres serveurs de bases de données peut différer.

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

Exemple 2

Ensuite, déclarez une fonction dans la partie SSDL (Store Schema Definition Language) de votre fichier .edmx. Le code suivant déclare la fonction AvgStudentGrade en langage SSDL :

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

Exemple 3

À présent, créez une méthode et mappez-la à la fonction déclarée dans le langage SSDL. La méthode dans la classe suivante est mappée à la fonction définie dans le langage SSDL (ci-dessus) à l'aide d'un attribut EdmFunctionAttribute. Lorsque cette méthode est appelée, la fonction correspondante dans la base de données est exécutée.

[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

Exemple 4

Enfin, appelez la méthode dans une requête LINQ to Entities. Le code suivant affiche le nom des étudiants et la moyenne des notes sur la console :

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

Voir aussi