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
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.
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ść .
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
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ść .
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 SalesOrderDetail
elementu .
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