Share via


Postupy: Volání modelově definovaných funkcí jako objektových metod

Toto téma popisuje, jak volat modelem definovanou funkci jako metodu objektu ObjectContext nebo jako statickou metodu ve vlastní třídě. Modelem definovaná funkce je funkce definovaná v konceptuálním modelu. Postupy v tématu popisují, jak tyto funkce volat přímo místo volání z LINQ na entity dotazy. Informace o volání modelem definovaných funkcí v dotazech LINQ to Entities naleznete v tématu Postupy: Volání modelem definovaných funkcí v dotazech.

Bez ohledu na to, jestli voláte modelem definovanou funkci jako metodu ObjectContext , nebo jako statickou metodu ve vlastní třídě, musíte nejprve namapovat metodu na modelem definovanou EdmFunctionAttributefunkci pomocí . Pokud však definujete metodu třídy ObjectContext , musíte použít QueryProvider vlastnost k zveřejnění zprostředkovatele LINQ, zatímco když definujete statickou metodu ve vlastní třídě, musíte použít Provider vlastnost vystavit zprostředkovatele LINQ. Další informace najdete v příkladech, které se řídí následujícími postupy.

Níže uvedené postupy poskytují základní osnovy pro volání modelem definované funkce jako metody pro ObjectContext objekt a jako statickou metodu ve vlastní třídě. Následující příklady obsahují podrobnější informace o krocích v postupech. Postupy předpokládají, že jste definovali funkci v konceptuálním modelu. Další informace naleznete v tématu Postupy: Definování vlastních funkcí v konceptuálním modelu.

Volání modelem definované funkce jako metody objektu ObjectContext

  1. Přidejte zdrojový soubor, který rozšíří částečnou třídu odvozenou ObjectContext z třídy, automaticky vygenerovanou nástroji Entity Framework. Definování zástupných procedur CLR v samostatném zdrojovém souboru zabrání ztrátě změn při opětovném vygenerování souboru.

  2. Přidejte do třídy ObjectContext metodu CLR (Common Language Runtime), která provede následující kroky:

    • Mapy k funkci definované v konceptuálním modelu. Chcete-li namapovat metodu, musíte u této metody použít EdmFunctionAttribute metodu. Všimněte si, že NamespaceName parametry FunctionName atributu jsou název oboru názvů konceptuálního modelu a název funkce v konceptuálním modelu. Rozlišení názvů funkcí pro LINQ rozlišují malá a velká písmena.

    • Vrátí výsledky Execute metody, která je vrácena QueryProvider vlastností.

  3. Volání metody jako člena instance ObjectContext třídy.

Volání modelem definované funkce jako statické metody ve vlastní třídě

  1. Přidejte do aplikace třídu pomocí statické metody, která provede následující:

    • Mapy k funkci definované v konceptuálním modelu. Chcete-li namapovat metodu, musíte u této metody použít EdmFunctionAttribute metodu. Všimněte si, že NamespaceName parametry FunctionName atributu jsou název oboru názvů konceptuálního modelu a název funkce v konceptuálním modelu.

    • IQueryable Přijme argument.

    • Vrátí výsledky Execute metody, která je vrácena Provider vlastností.

  2. Volání metody jako člena statické metody ve vlastní třídě

Příklad 1

Volání modelem definované funkce jako metody objektu ObjectContext

Následující příklad ukazuje, jak volat modelem definovanou funkci jako metodu objektu ObjectContext . V příkladu se používá model AdventureWorks Sales Model.

Představte si níže uvedenou funkci koncepčního modelu, která vrací výnosy za určitý produkt. (Informace o přidání funkce do konceptuálního modelu najdete v tématu Postupy: Definování vlastních funkcí v konceptuálním modelu.)

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

Příklad 2

Následující kód přidá metodu AdventureWorksEntities do třídy, která se mapuje na funkci konceptuálního modelu výše.

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

Příklad 3

Následující kód volá výše uvedenou metodu, aby se zobrazily výnosy za produkt pro zadaný produkt:

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

Příklad 4

Následující příklad ukazuje, jak volat modelem definovanou funkci, která vrací kolekci (jako IQueryable<T> objekt). Podívejte se na níže uvedené koncepční funkce modelu, která vrátí všechny SalesOrderDetails id daného 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>

Příklad 5

Následující kód přidá metodu AdventureWorksEntities do třídy, která se mapuje na funkci konceptuálního modelu výše.

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

Příklad 6

Následující kód volá metodu. Všimněte si, že vrácený IQueryable<T> dotaz je dále zpřesněný tak, aby vracel součty řádků pro každou z nich SalesOrderDetail.

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

Příklad 7

Volání modelem definované funkce jako statické metody ve vlastní třídě

Další příklad ukazuje, jak volat modelem definovanou funkci jako statickou metodu ve vlastní třídě. V příkladu se používá model AdventureWorks Sales Model.

Poznámka:

Když zavoláte modelem definovanou funkci jako statickou metodu ve vlastní třídě, musí modelem definovaná funkce přijmout kolekci a vrátit agregaci hodnot v kolekci.

Představte si níže funkci konceptuálního modelu, která vrací výnosy produktů pro kolekci SalesOrderDetail. (Informace o přidání funkce do konceptuálního modelu najdete v tématu Postupy: Definování vlastních funkcí v konceptuálním modelu.)

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

Příklad 8

Následující kód přidá do vaší aplikace třídu, která obsahuje statickou metodu, která se mapuje na funkci konceptuálního modelu výše.

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

Příklad 9

Následující kód volá metodu uvedenou výše, aby se zobrazily výnosy produktů pro kolekci 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

Viz také