Delen via


Procedure: Modelgedefinieerde functies aanroepen als objectmethoden

In dit onderwerp wordt beschreven hoe u een modelgedefinieerde functie aanroept als een methode voor een ObjectContext object of als een statische methode in een aangepaste klasse. Een modelgedefinieerde functie is een functie die is gedefinieerd in het conceptuele model. In de procedures in het onderwerp wordt beschreven hoe u deze functies rechtstreeks aanroept in plaats van ze aan te roepen van LINQ naar entiteitenquery's. Zie Procedure: Door model gedefinieerde functies aanroepen in query's van LINQ naar entiteiten voor informatie over het aanroepen van modelgedefinieerde functies in query's.

Ongeacht of u een modelgedefinieerde functie aanroept als een ObjectContext methode of als een statische methode in een aangepaste klasse, moet u de methode eerst toewijzen aan de modelgedefinieerde functie met een EdmFunctionAttribute. Wanneer u echter een methode op de ObjectContext klasse definieert, moet u de QueryProvider eigenschap gebruiken om de LINQ-provider beschikbaar te maken. Wanneer u een statische methode definieert voor een aangepaste klasse, moet u de Provider eigenschap gebruiken om de LINQ-provider beschikbaar te maken. Zie de voorbeelden die de onderstaande procedures volgen voor meer informatie.

De onderstaande procedures bieden overzichten op hoog niveau voor het aanroepen van een door een model gedefinieerde functie als een methode voor een ObjectContext object en als een statische methode voor een aangepaste klasse. De volgende voorbeelden bevatten meer informatie over de stappen in de procedures. Bij de procedures wordt ervan uitgegaan dat u een functie hebt gedefinieerd in het conceptuele model. Zie Voor meer informatie : Aangepaste functies definiëren in het conceptuele model.

Een modelgedefinieerde functie aanroepen als een methode op een ObjectContext-object

  1. Voeg een bronbestand toe om de gedeeltelijke klasse die is afgeleid van de ObjectContext klasse, automatisch gegenereerd door de Entity Framework-hulpprogramma's uit te breiden. Als u de CLR-stub in een afzonderlijk bronbestand definieert, kunnen de wijzigingen niet verloren gaan wanneer het bestand opnieuw wordt gegenereerd.

  2. Voeg een CLR-methode (Common Language Runtime) toe aan uw ObjectContext klasse die het volgende doet:

    • Kaarten aan de functie die is gedefinieerd in het conceptuele model. Als u de methode wilt toewijzen, moet u een EdmFunctionAttribute op de methode toepassen. Houd er rekening mee dat de NamespaceName en FunctionName parameters van het kenmerk respectievelijk de naamruimtenaam van het conceptuele model en de functienaam in het conceptuele model zijn. Functienaamomzetting voor LINQ is hoofdlettergevoelig.

    • Retourneert de resultaten van de Execute methode die wordt geretourneerd door de QueryProvider eigenschap.

  3. Roep de methode aan als lid van een exemplaar van de ObjectContext klasse.

Een modelgedefinieerde functie aanroepen als statische methode in een aangepaste klasse

  1. Voeg een klasse toe aan uw toepassing met een statische methode die het volgende doet:

    • Kaarten aan de functie die is gedefinieerd in het conceptuele model. Als u de methode wilt toewijzen, moet u een EdmFunctionAttribute op de methode toepassen. Houd er rekening mee dat de NamespaceName en FunctionName parameters van het kenmerk respectievelijk de naamruimtenaam van het conceptuele model en de functienaam in het conceptuele model zijn.

    • Accepteert een IQueryable argument.

    • Retourneert de resultaten van de Execute methode die wordt geretourneerd door de Provider eigenschap.

  2. De methode aanroepen als lid van een statische methode in de aangepaste klasse

Voorbeeld 1

Een modelgedefinieerde functie aanroepen als een methode op een ObjectContext-object

In het volgende voorbeeld ziet u hoe u een modelgedefinieerde functie aanroept als een methode voor een ObjectContext object. In het voorbeeld wordt het AdventureWorks Sales Model gebruikt.

Houd rekening met de conceptuele modelfunctie hieronder die productopbrengsten retourneert voor een opgegeven product. (Zie voor meer informatie over het toevoegen van de functie aan uw conceptueel model Procedure: Aangepaste functies definiëren in het conceptuele model.)

<Function Name="GetProductRevenue" ReturnType="Edm.Decimal">
  <Parameter Name="productID" Type="Edm.Int32" />
  <DefiningExpression>
    SUM( SELECT VALUE((s.UnitPrice - s.UnitPriceDiscount)  * s.OrderQty)
    FROM AdventureWorksEntities.SalesOrderDetails as s
    WHERE s.ProductID = productID)
  </DefiningExpression>
</Function>

Voorbeeld 2

Met de volgende code wordt een methode toegevoegd aan de AdventureWorksEntities klasse die is toegewezen aan de bovenstaande conceptuele modelfunctie.

public partial class AdventureWorksEntities : ObjectContext
{
    [EdmFunction("AdventureWorksModel", "GetProductRevenue")]
    public decimal? GetProductRevenue(int productId)
    {
        return this.QueryProvider.Execute<decimal?>(Expression.Call(
            Expression.Constant(this),
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(productId, typeof(int))));
    }
}
Partial Public Class AdventureWorksEntities
    Inherits ObjectContext

    <EdmFunction("AdventureWorksModel", "GetProductRevenue")>
    Public Function GetProductRevenue(ByVal details As _
                    IQueryable(Of SalesOrderDetail)) As _
                    System.Nullable(Of Decimal)
        Return Me.QueryProvider.Execute(Of System.Nullable(Of Decimal)) _
            (Expression.[Call](Expression.Constant(Me), _
            DirectCast(MethodInfo.GetCurrentMethod(), MethodInfo), _
            Expression.Constant(details, GetType(IQueryable(Of SalesOrderDetail)))))
    End Function
End Class

Voorbeeld 3

Met de volgende code wordt de bovenstaande methode aangeroepen om de productopbrengst voor een opgegeven product weer te geven:

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    Console.WriteLine(AWEntities.GetProductRevenue(productId));
}
Using AWEntities As New AdventureWorksEntities()

    Dim productId As Integer = 776

    Dim details = From s In AWEntities.SalesOrderDetails _
                  Where s.ProductID = productId _
                  Select s

    Console.WriteLine(AWEntities.GetProductRevenue(details))
End Using

Voorbeeld 4

In het volgende voorbeeld ziet u hoe u een modelgedefinieerde functie aanroept die een verzameling retourneert (als een IQueryable<T> object). Bekijk de conceptuele modelfunctie hieronder die alle SalesOrderDetails retourneert voor een bepaalde product-id.

<Function Name="GetDetailsById" 
          ReturnType="Collection(AdventureWorksModel.SalesOrderDetail)">
  <Parameter Name="productID" Type="Edm.Int32" />
  <DefiningExpression>
    SELECT VALUE s
    FROM AdventureWorksEntities.SalesOrderDetails AS s
    WHERE s.ProductID = productID
  </DefiningExpression>
</Function>

Voorbeeld 5

Met de volgende code wordt een methode toegevoegd aan de AdventureWorksEntities klasse die is toegewezen aan de bovenstaande conceptuele modelfunctie.

public partial class AdventureWorksEntities : ObjectContext
{
    [EdmFunction("AdventureWorksModel", "GetDetailsById")]
    public IQueryable<SalesOrderDetail> GetDetailsById(int productId)
    {
        return this.QueryProvider.CreateQuery<SalesOrderDetail>(Expression.Call(
            Expression.Constant(this),
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(productId, typeof(int))));
    }
}
Partial Public Class AdventureWorksEntities
    Inherits ObjectContext
    <EdmFunction("AdventureWorksModel", "GetDetailsById")> _
    Public Function GetDetailsById(ByVal productId As Integer) _
            As IQueryable(Of SalesOrderDetail)
        Return Me.QueryProvider.CreateQuery(Of SalesOrderDetail) _
            (Expression.[Call](Expression.Constant(Me), _
             DirectCast(MethodInfo.GetCurrentMethod(), MethodInfo), _
             Expression.Constant(productId, GetType(Integer))))
    End Function
End Class

Voorbeeld 6

Met de volgende code wordt de methode aangeroepen. Houd er rekening mee dat de geretourneerde IQueryable<T> query verder wordt verfijnd om regeltotalen voor elke SalesOrderDetailquery te retourneren.

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    var lineTotals = AWEntities.GetDetailsById(productId).Select(d =>d.LineTotal);

    foreach(var lineTotal in lineTotals)
    {
        Console.WriteLine(lineTotal);
    }
}
Using AWEntities As New AdventureWorksEntities()
    Dim productId As Integer = 776

    Dim lineTotals = AWEntities.GetDetailsById(productId).[Select](Function(d) d.LineTotal)

    For Each lineTotal In lineTotals
        Console.WriteLine(lineTotal)
    Next

Voorbeeld 7

Een modelgedefinieerde functie aanroepen als een statische methode in een aangepaste klasse

In het volgende voorbeeld ziet u hoe u een modelgedefinieerde functie aanroept als een statische methode in een aangepaste klasse. In het voorbeeld wordt het AdventureWorks Sales Model gebruikt.

Notitie

Wanneer u een modelgedefinieerde functie aanroept als een statische methode voor een aangepaste klasse, moet de door het model gedefinieerde functie een verzameling accepteren en een aggregatie van waarden in de verzameling retourneren.

Bekijk de conceptuele modelfunctie hieronder die productopbrengsten retourneert voor een SalesOrderDetail-verzameling. (Zie voor meer informatie over het toevoegen van de functie aan uw conceptueel model Procedure: Aangepaste functies definiëren in het conceptuele model.)

<Function Name="GetProductRevenue" ReturnType="Edm.Decimal">
  <Parameter Name="details" Type="Collection(AdventureWorksModel.SalesOrderDetail)" />
  <DefiningExpression>
    SUM( SELECT VALUE((s.UnitPrice - s.UnitPriceDiscount)  * s.OrderQty)
    FROM details as s)
  </DefiningExpression>
</Function>

Voorbeeld 8

Met de volgende code wordt een klasse toegevoegd aan uw toepassing die een statische methode bevat die is toegewezen aan de bovenstaande conceptuele modelfunctie.

public class MyClass
{
    [EdmFunction("AdventureWorksModel", "GetProductRevenue")]
    public static decimal? GetProductRevenue(IQueryable<SalesOrderDetail> details)
    {
        return details.Provider.Execute<decimal?>(Expression.Call(
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(details, typeof(IQueryable<SalesOrderDetail>))));
    }
}
Public Class [MyClass]
    <EdmFunction("AdventureWorksModel", "GetProductRevenue")> _
    Public Shared Function GetProductRevenue(ByVal details As _
                IQueryable(Of SalesOrderDetail)) As _
                System.Nullable(Of Decimal)
        Return details.Provider.Execute(Of System.Nullable(Of Decimal)) _
            (Expression.[Call](DirectCast(MethodInfo.GetCurrentMethod(), MethodInfo), _
            Expression.Constant(details, GetType(IQueryable(Of SalesOrderDetail)))))
    End Function
End Class

Voorbeeld 9

Met de volgende code wordt de bovenstaande methode aangeroepen om de productopbrengst voor een SalesOrderDetail-verzameling weer te geven:

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    var details = from s in AWEntities.SalesOrderDetails
                  where s.ProductID == productId select s;

    Console.WriteLine(MyClass.GetProductRevenue(details));
}
Using AWEntities As New AdventureWorksEntities()
    Dim productId As Integer = 776

    Dim details = From s In AWEntities.SalesOrderDetails _
                  Where s.ProductID = productId _
                  Select s

    Console.WriteLine([MyClass].GetProductRevenue(details))
End Using

Zie ook