Share via


Procedimiento para llamar a funciones de base de datos personalizadas

En este tema se describe cómo llamar a las funciones personalizadas definidas en la base de datos desde consultas LINQ to Entities.

Las funciones de base de datos llamadas desde LINQ to Entities se ejecutan en la base de datos. La ejecución de funciones en la base de datos puede mejorar el rendimiento de la aplicación.

El procedimiento siguiente proporciona un esquema general para llamar a una función de base de datos personalizada. El ejemplo que sigue proporciona más detalles sobre los pasos del procedimiento.

Para llamar a funciones personalizadas definidas en la base de datos

  1. Cree una función personalizada en la base de datos.

    Para obtener más información sobre cómo crear funciones personalizadas en SQL Server, vea CREATE FUNCTION (Transact-SQL).

  2. Declare una función en el lenguaje de definición de esquemas de almacenamiento (SSDL) del archivo .edmx. El nombre de la función debe coincidir con el nombre de la función declarada en la base de datos.

    Para obtener más información, vea Elementos de función (SSDL).

  3. Agregue un método correspondiente a una clase del código de la aplicación y aplique un atributo EdmFunctionAttribute al método. Tenga en cuenta que los parámetros NamespaceName y FunctionName de dicho atributo son el nombre del espacio de nombres del modelo conceptual y el nombre de la función en el modelo conceptual, respectivamente. La resolución del nombre de la función para LINQ distingue entre mayúsculas y minúsculas.

  4. Llame al método en una consulta LINQ to Entities.

Ejemplo 1

En el ejemplo siguiente se muestra cómo llamar a una función de base de datos personalizada desde una consulta LINQ to Entities. En el ejemplo se usa el modelo School. Para obtener información sobre el modelo School, vea Crear la base de datos de ejemplo School y Generar el archivo .edmx de School.

El código siguiente agrega la función AvgStudentGrade a la base de datos de ejemplo School.

Nota

Los pasos para llamar a una función de base de datos personalizada son los mismos, independientemente del servidor de bases de datos. Sin embargo, el código siguiente es específico para crear una función en una base de datos de SQL Server. El código para crear una función personalizada en otros servidores de bases de datos puede variar.

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

Ejemplo 2

A continuación, declare una función en el lenguaje de definición de esquemas de almacenamiento (SSDL) del archivo .edmx. El código siguiente declara la función AvgStudentGrade en SSDL:

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

Ejemplo 3

Ahora, cree un método y asígneselo a la función declarada en SSDL. El método de la clase siguiente se asigna a dicha función usando un atributo EdmFunctionAttribute. Cuando se llama a este método, se ejecuta la función correspondiente en la base de datos.

[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

Ejemplo 4

Por último, llame al método en una consulta LINQ to Entities. El código siguiente muestra en la consola los apellidos de los alumnos y sus notas medias:

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

Consulte también