Freigeben über


Vorgehensweise: Aufrufen von modell-definierten Funktionen als Objektmethoden

In diesem Thema wird beschrieben, wie eine modelldefinierte Funktion als Methode für ein ObjectContext Objekt oder als statische Methode für eine benutzerdefinierte Klasse aufgerufen wird. Eine modelldefinierte Funktion ist eine Funktion, die im konzeptionellen Modell definiert ist. In den Verfahren im Thema wird beschrieben, wie diese Funktionen direkt aufgerufen werden, anstatt sie von LINQ to Entities-Abfragen aufzurufen. Informationen zum Aufrufen modelldefinierter Funktionen in LINQ to Entities-Abfragen finden Sie unter How to: Call Model-Defined Functions in Queries.

Unabhängig davon, ob Sie eine modelldefinierte Funktion als ObjectContext Methode oder als statische Methode für eine benutzerdefinierte Klasse aufrufen, müssen Sie die Methode zuerst der modelldefinierte Funktion mit einer EdmFunctionAttributezuordnen. Wenn Sie jedoch eine Methode für die ObjectContext Klasse definieren, müssen Sie die QueryProvider Eigenschaft verwenden, um den LINQ-Anbieter verfügbar zu machen, während Sie beim Definieren einer statischen Methode für eine benutzerdefinierte Klasse die Provider Eigenschaft verwenden müssen, um den LINQ-Anbieter verfügbar zu machen. Weitere Informationen finden Sie in den Beispielen, die die folgenden Verfahren befolgen.

Die folgenden Verfahren enthalten allgemeine Gliederungen zum Aufrufen einer modelldefinierten Funktion als Methode für ein ObjectContext Objekt und als statische Methode für eine benutzerdefinierte Klasse. Die folgenden Beispiele enthalten weitere Details zu den Schritten in den Verfahren. Bei den Prozeduren wird davon ausgegangen, dass Sie eine Funktion im konzeptionellen Modell definiert haben. Weitere Informationen finden Sie unter How to: Define Custom Functions in the Conceptual Model.

So rufen Sie eine modelldefinierte Funktion als Methode für ein ObjectContext-Objekt auf

  1. Fügen Sie eine Quelldatei hinzu, um die von der ObjectContext Klasse abgeleitete partielle Klasse zu erweitern, die automatisch von den Entity Framework-Tools generiert wird. Durch das Definieren des CLR-Stubs in einer separaten Quelldatei wird verhindert, dass die Änderungen verloren gehen, wenn die Datei neu generiert wird.

  2. Fügen Sie Ihrer ObjectContext Klasse eine Common Language Runtime (CLR)-Methode hinzu, die folgendes ausführt:

    • Es ordnet die im konzeptionellen Modell definierte Funktion zu. Um die Methode abzubilden, müssen Sie eine EdmFunctionAttribute auf die Methode anwenden. Beachten Sie, dass die NamespaceName Parameter und FunctionName Parameter des Attributs der Namespacename des konzeptionellen Modells bzw. des Funktionsnamens im konzeptionellen Modell sind. Bei der Auflösung von Funktionsnamen für LINQ wird die Groß-/Kleinschreibung beachtet.

    • Gibt die Ergebnisse der Execute Methode zurück, die von der QueryProvider Eigenschaft zurückgegeben wird.

  3. Rufen Sie die Methode als Member für eine Instanz der ObjectContext Klasse auf.

So rufen Sie eine modelldefinierte Funktion als statische Methode für eine benutzerdefinierte Klasse auf

  1. Fügen Sie Ihrer Anwendung eine Klasse mit einer statischen Methode hinzu, die folgende Aktionen ausführt:

    • Ordnet die im konzeptionellen Modell definierte Funktion zu. Um die Methode zu kartieren, müssen Sie ein EdmFunctionAttribute auf die Methode anwenden. Beachten Sie, dass die NamespaceName Parameter und FunctionName Parameter des Attributs der Namespacename des konzeptionellen Modells bzw. des Funktionsnamens im konzeptionellen Modell sind.

    • Akzeptiert ein IQueryable Argument.

    • Gibt die Ergebnisse der Execute Methode zurück, die von der Provider Eigenschaft zurückgegeben wird.

  2. Aufrufen der Methode als Mitglied einer statischen Methode für die benutzerdefinierte Klasse

Beispiel 1

Aufrufen einer Model-Defined Function als Methode für ein ObjectContext-Objekt

Im folgenden Beispiel wird veranschaulicht, wie eine modelldefinierte Funktion als Methode für ein ObjectContext Objekt aufgerufen wird. Im Beispiel wird das AdventureWorks-Vertriebsmodell verwendet.

Betrachten Sie die konzeptionelle Modellfunktion unten, die Produkteinnahmen für ein bestimmtes Produkt zurückgibt. (Informationen zum Hinzufügen der Funktion zu Ihrem konzeptionellen Modell finden Sie unter How to: Define Custom Functions in the Conceptual 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>

Beispiel 2

Der folgende Code fügt der AdventureWorksEntities Klasse eine Methode hinzu, die der konzeptionellen Modellfunktion oben zugeordnet ist.

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

Beispiel 3

Der folgende Code ruft die oben genannte Methode auf, um den Produktumsatz für ein bestimmtes Produkt anzuzeigen:

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

Beispiel 4

Im folgenden Beispiel wird veranschaulicht, wie eine modelldefinierte Funktion aufgerufen wird, die eine Auflistung (als IQueryable<T> Objekt) zurückgibt. Betrachten Sie die konzeptionelle Modellfunktion unten, die alle SalesOrderDetails für eine bestimmte Produkt-ID zurückgibt.

<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>

Beispiel 5

Der folgende Code fügt der AdventureWorksEntities Klasse eine Methode hinzu, die der konzeptionellen Modellfunktion oben zugeordnet ist.

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

Beispiel 6

Der folgende Code ruft die Methode auf. Beachten Sie, dass die zurückgegebene IQueryable<T> Abfrage weiter verfeinert wird, um Zeilensummen für jedes Ergebnis SalesOrderDetailzurückzugeben.

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

Beispiel 7

Aufrufen einer Model-Defined Function als statische Methode für eine benutzerdefinierte Klasse

Im nächsten Beispiel wird veranschaulicht, wie eine modelldefinierte Funktion als statische Methode für eine benutzerdefinierte Klasse aufgerufen wird. Im Beispiel wird das AdventureWorks-Vertriebsmodell verwendet.

Hinweis

Wenn Sie eine modelldefinierte Funktion als statische Methode für eine benutzerdefinierte Klasse aufrufen, muss die modelldefinierte Funktion eine Auflistung akzeptieren und eine Aggregation von Werten in der Auflistung zurückgeben.

Betrachten Sie die konzeptionelle Modellfunktion unten, die Produkteinnahmen für eine SalesOrderDetail-Auflistung zurückgibt. (Informationen zum Hinzufügen der Funktion zu Ihrem konzeptionellen Modell finden Sie unter How to: Define Custom Functions in the Conceptual 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>

Beispiel 8

Der folgende Code fügt Ihrer Anwendung eine Klasse hinzu, die eine statische Methode enthält, die der konzeptionellen Modellfunktion oben zugeordnet ist.

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

Beispiel 9

Der folgende Code ruft die oben genannte Methode auf, um den Produktumsatz für eine SalesOrderDetail-Auflistung anzuzeigen:

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

Siehe auch