Udostępnij przez


Instrukcje: Wywoływanie funkcji definiowanych przez model jako metod obiektu

W tym temacie opisano sposób wywoływania funkcji zdefiniowanej przez model jako metody w ObjectContext obiekcie lub jako metody statycznej w klasie niestandardowej. Funkcja zdefiniowana przez model to funkcja zdefiniowana w modelu koncepcyjnym. Procedury w temacie opisują sposób wywoływania tych funkcji bezpośrednio zamiast wywoływania ich z zapytań LINQ to Entities. Aby uzyskać informacje na temat wywoływania funkcji zdefiniowanych przez model w zapytaniach LINQ to Entities, zobacz Instrukcje: wywoływanie funkcji zdefiniowanych przez model w zapytaniach.

Niezależnie od tego, czy wywołujesz funkcję zdefiniowaną przez model jako metodę ObjectContext , czy jako metodę statyczną w klasie niestandardowej, musisz najpierw zamapować metodę na funkcję zdefiniowaną przez model przy użyciu EdmFunctionAttributeklasy . Jednak podczas definiowania metody w ObjectContext klasie należy użyć QueryProvider właściwości , aby uwidocznić dostawcę LINQ, natomiast podczas definiowania metody statycznej w klasie niestandardowej należy użyć Provider właściwości , aby uwidocznić dostawcę LINQ. Aby uzyskać więcej informacji, zobacz przykłady, które są zgodne z poniższymi procedurami.

Poniższe procedury zawierają ogólne konspektu dotyczące wywoływania funkcji zdefiniowanej przez model jako metody w ObjectContext obiekcie i jako metody statycznej w klasie niestandardowej. Poniższe przykłady zawierają więcej szczegółowych informacji na temat kroków opisanych w procedurach. W procedurach przyjęto założenie, że zdefiniowano funkcję w modelu koncepcyjnym. Aby uzyskać więcej informacji, zobacz How to: Define Custom Functions in the Conceptual Model (Jak definiować funkcje niestandardowe w modelu koncepcyjnym).

Aby wywołać funkcję zdefiniowaną przez model jako metodę w obiekcie ObjectContext

  1. Dodaj plik źródłowy, aby rozszerzyć klasę częściową pochodzącą z ObjectContext klasy wygenerowanej automatycznie przez narzędzia Platformy Entity Framework. Zdefiniowanie wycinku CLR w osobnym pliku źródłowym uniemożliwi utratę zmian podczas ponownego generowania pliku.

  2. Dodaj metodę środowiska uruchomieniowego języka wspólnego (CLR) do ObjectContext klasy, która wykonuje następujące czynności:

    • Mapy do funkcji zdefiniowanej w modelu koncepcyjnym. Aby zamapować metodę, należy zastosować metodę EdmFunctionAttribute . Należy pamiętać, że NamespaceName parametry i FunctionName atrybutu są odpowiednio nazwą przestrzeni nazw modelu koncepcyjnego i nazwą funkcji w modelu koncepcyjnym. Rozpoznawanie nazw funkcji dla LINQ uwzględnia wielkość liter.

    • Zwraca wyniki Execute metody zwracanej przez QueryProvider właściwość .

  3. Wywołaj metodę jako element członkowski w wystąpieniu ObjectContext klasy.

Aby wywołać funkcję zdefiniowaną przez model jako metodę statyczną w klasie niestandardowej

  1. Dodaj klasę do aplikacji przy użyciu metody statycznej, która wykonuje następujące czynności:

    • Mapy do funkcji zdefiniowanej w modelu koncepcyjnym. Aby zamapować metodę, należy zastosować metodę EdmFunctionAttribute . Należy pamiętać, że NamespaceName parametry i FunctionName atrybutu są odpowiednio nazwą przestrzeni nazw modelu koncepcyjnego i nazwą funkcji w modelu koncepcyjnym.

    • IQueryable Akceptuje argument.

    • Zwraca wyniki Execute metody zwracanej przez Provider właściwość .

  2. Wywoływanie metody jako składowej metody statycznej w klasie niestandardowej

Przykład 1

Wywoływanie funkcji zdefiniowanej przez model jako metody w obiekcie ObjectContext

W poniższym przykładzie pokazano, jak wywołać funkcję zdefiniowaną przez model jako metodę w ObjectContext obiekcie. W przykładzie użyto modelu AdventureWorks Sales Model.

Rozważmy poniżej funkcję modelu koncepcyjnego, która zwraca przychody z produktu dla określonego produktu. (Aby uzyskać informacje na temat dodawania funkcji do modelu koncepcyjnego, zobacz Instrukcje: definiowanie funkcji niestandardowych w modelu koncepcyjnym).

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

Przykład 2

Poniższy kod dodaje metodę do AdventureWorksEntities klasy, która mapuje się na funkcję modelu koncepcyjnego powyżej.

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

Przykład 3

Poniższy kod wywołuje metodę powyżej, aby wyświetlić przychód produktu dla określonego produktu:

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

Przykład 4

W poniższym przykładzie pokazano, jak wywołać funkcję zdefiniowaną przez model, która zwraca kolekcję (jako IQueryable<T> obiekt). Rozważmy poniższą funkcję modelu koncepcyjnego, która zwraca wszystkie SalesOrderDetails wartości dla danego identyfikatora produktu.

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

Przykład 5

Poniższy kod dodaje metodę do AdventureWorksEntities klasy, która mapuje się na funkcję modelu koncepcyjnego powyżej.

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

Przykład 6

Poniższy kod wywołuje metodę . Zwróć uwagę, że zwrócone IQueryable<T> zapytanie jest bardziej uściśline, aby zwracać sumy wierszy dla każdego SalesOrderDetailelementu .

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

Przykład 7

Wywoływanie funkcji zdefiniowanej przez model jako metody statycznej w klasie niestandardowej

W następnym przykładzie pokazano, jak wywołać funkcję zdefiniowaną przez model jako metodę statyczną w klasie niestandardowej. W przykładzie użyto modelu AdventureWorks Sales Model.

Uwaga

W przypadku wywoływania funkcji zdefiniowanej przez model jako metody statycznej w klasie niestandardowej funkcja zdefiniowana przez model musi akceptować kolekcję i zwracać agregację wartości w kolekcji.

Rozważmy poniższą funkcję modelu koncepcyjnego, która zwraca przychody z produktu dla kolekcji SalesOrderDetail. (Aby uzyskać informacje na temat dodawania funkcji do modelu koncepcyjnego, zobacz Instrukcje: definiowanie funkcji niestandardowych w modelu koncepcyjnym).

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

Przykład 8

Poniższy kod dodaje klasę do aplikacji, która zawiera metodę statyczną, która mapuje na funkcję modelu koncepcyjnego powyżej.

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

Przykład 9

Poniższy kod wywołuje metodę powyżej, aby wyświetlić przychód produktu dla kolekcji SalesOrderDetail:

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

Zobacz też