Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico descreve como chamar uma função definida por modelo como um método em um ObjectContext objeto ou como um método estático em uma classe personalizada. Uma função definida pelo modelo é uma função definida no modelo conceitual. Os procedimentos no tópico descrevem como chamar essas funções diretamente, em vez de chamá-las de consultas do LINQ to Entities. Para obter informações sobre como chamar funções definidas pelo modelo em consultas LINQ to Entities, consulte Como chamar funções definidas pelo modelo em consultas.
Se você chamar uma função definida pelo modelo como um ObjectContext método ou como um método estático em uma classe personalizada, primeiro deverá mapear o método para a função definida pelo modelo com um EdmFunctionAttribute. No entanto, ao definir um método na ObjectContext classe, você deve usar a QueryProvider propriedade para expor o provedor LINQ, enquanto quando você define um método estático em uma classe personalizada, deve usar a Provider propriedade para expor o provedor LINQ. Para obter mais informações, consulte os exemplos que seguem os procedimentos abaixo.
Os procedimentos abaixo fornecem esboços de alto nível para chamar uma função definida pelo modelo como um método em um objeto ObjectContext e como um método estático em uma classe personalizada. Os exemplos a seguir fornecem mais detalhes sobre as etapas nos procedimentos. Os procedimentos pressupõem que você tenha definido uma função no modelo conceitual. Para obter mais informações, consulte Como definir funções personalizadas no modelo conceitual.
Para chamar uma função definida pelo modelo como um método em um objeto ObjectContext
Adicione um arquivo de origem para estender a classe parcial derivada da ObjectContext classe, gerada automaticamente pelas ferramentas do Entity Framework. Definir o stub clr em um arquivo de origem separado impedirá que as alterações sejam perdidas quando o arquivo for regenerado.
Adicione um método CLR (Common Language Runtime) à sua ObjectContext classe que faça o seguinte:
Mapeia para a função definida no modelo conceitual. Para mapear o método, você deve aplicar um EdmFunctionAttribute ao método. Observe que os parâmetros NamespaceName e FunctionName do atributo são o nome do namespace do modelo conceitual e o nome da função no modelo conceitual, respectivamente. A resolução de nomes de funções para LINQ diferencia maiúsculas de minúsculas.
Retorna os resultados do Execute método retornado pela QueryProvider propriedade.
Chame o método como um membro em uma instância da classe ObjectContext.
Para chamar uma função definida pelo modelo como método estático em uma classe personalizada
Adicione uma classe ao seu aplicativo com um método estático que faz o seguinte:
Mapeia para a função definida no modelo conceitual. Para mapear o método, você deve aplicar um EdmFunctionAttribute ao método. Observe que os parâmetros NamespaceName e FunctionName do atributo são, respectivamente, o nome do namespace do modelo conceitual e o nome da função no modelo conceitual.
Aceita um IQueryable argumento.
Retorna os resultados do Execute método retornado pela Provider propriedade.
Chamar o método como membro de um método estático na classe personalizada
Exemplo 1
Chamando uma função definida pelo modelo como um método em um objeto ObjectContext
O exemplo a seguir demonstra como chamar uma função definida pelo modelo como um método em um ObjectContext objeto. O exemplo usa o Modelo de Vendas AdventureWorks.
Considere a função de modelo conceitual abaixo que retorna a receita do produto para um produto especificado. (Para obter informações sobre como adicionar a função ao modelo conceitual, consulte Como definir funções personalizadas no modelo conceitual.)
<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>
Exemplo 2
O código a seguir adiciona um método à classe AdventureWorksEntities que mapeia para a função de modelo conceitual acima.
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
Exemplo 3
O código a seguir chama o método acima para exibir a receita do produto para um produto especificado:
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
Exemplo 4
O exemplo a seguir demonstra como chamar uma função definida por modelo que retorna uma coleção (como um IQueryable<T> objeto). Considere a função de modelo conceitual abaixo que retorna todos os SalesOrderDetails para uma determinada ID de produto.
<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>
Exemplo 5
O código a seguir adiciona um método à classe AdventureWorksEntities que mapeia para a função de modelo conceitual acima.
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
Exemplo 6
O código a seguir chama o método. Observe que a consulta retornada IQueryable<T> é ainda mais refinada para retornar totais de linha para cada 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
Exemplo 7
Chamando uma função Model-Defined como um método estático em uma classe personalizada
O exemplo a seguir demonstra como chamar uma função definida por modelo como um método estático em uma classe personalizada. O exemplo usa o Modelo de Vendas AdventureWorks.
Observação
Quando você chama uma função definida pelo modelo como um método estático em uma classe personalizada, a função definida pelo modelo deve aceitar uma coleção e retornar uma agregação de valores na coleção.
Considere a função de modelo conceitual abaixo que retorna a receita do produto para uma coleção SalesOrderDetail. (Para obter informações sobre como adicionar a função ao modelo conceitual, consulte Como definir funções personalizadas no modelo conceitual.)
<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>
Exemplo 8
O código a seguir adiciona uma classe ao seu aplicativo que contém um método estático que é mapeado para a função de modelo conceitual acima.
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
Exemplo 9
O código a seguir chama o método acima para exibir a receita do produto para uma coleção 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