Compartilhar via


Como: o chamar funções definidas como métodos de objeto

Este tópico descreve como chamar uma função o definida como um método em um objeto de ObjectContext ou como um método estático em uma classe personalizada. Uma função definida por modelo é uma função definida no modelo conceitual. O tópico descrevem como chamar essas funções diretamente em vez de chamá-los de consultas LINQ to Entities. Para obter informações sobre como chamar funções definidas por modelo em consultas do LINQ to Entities, consulte Como chamar funções definidas por modelo em consultas.

Se você chamar uma função o definida como um método de ObjectContext ou como um método estático em uma classe personalizada, primeiro você deve mapear o método à função definida com o EdmFunctionAttribute. No entanto, quando você define um método na classe de ObjectContext , você deve usar a propriedade de QueryProvider para expor o provedor LINQ, enquanto quando você define um método estático em uma classe personalizada, você deve usar a propriedade de Provider para expor o provedor LINQ. Para obter mais informações, consulte os exemplos a seguir os procedimentos abaixo.

Os procedimentos a seguir fornecem contornos de alto nível para chamar uma função o definida como um método em um objeto de 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 presumem que você definiu 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 o definida como um método em um objeto ObjectContext

  1. Adicione um arquivo de origem para estender a classe parcial derivada da classe de ObjectContext , gerado automaticamente por ferramentas de Entity Framework. Defina o stub de CLR em um arquivo de origem separado impedirá que as alterações sejam perdidas quando o arquivo for regenerado.

  2. Adicione um método do Common Language Runtime (CLR) a sua classe de ObjectContext que faz o seguinte:

    • Mapeados para a função definida no modelo conceitual. Para mapear o método, você deve aplicar EdmFunctionAttribute para o método. Observe que os parâmetros de NamespaceName e de FunctionName de atributo é o nome do espaço do modelo conceitual e o nome da função no modelo conceitual, respectivamente. A resolução de nomes de função para LINQ diferencia maiúsculas de minúsculas.

    • Retorna os resultados do método de Execute retornado pela propriedade de QueryProvider .

  3. Chame o método como um membro em uma instância da classe de ObjectContext .

Para chamar uma função o definida como o método estático em uma classe personalizada

  1. Adicionar uma classe ao seu aplicativo com um método estático que faça o seguinte:

    • Mapeados para a função definida no modelo conceitual. Para mapear o método, você deve aplicar EdmFunctionAttribute para o método. Observe que os parâmetros de NamespaceName e de FunctionName de atributo é o nome do espaço do modelo conceitual e o nome da função no modelo conceitual, respectivamente.

    • Aceita um argumento de IQueryable .

    • Retorna os resultados do método de Execute retornado pela propriedade de Provider .

  2. Chame o método como um membro um método estático na classe personalizada

Exemplo 1

Chamando uma função o definida como um método em um objeto de ObjectContext

O exemplo a seguir demonstra como chamar uma função o definida como um método em um objeto de ObjectContext . O exemplo usa o Modelo de Vendas do AdventureWorks.

Considere a função do modelo conceitual abaixo do rendimento do produto returns para um produto especificado. (Para obter mais 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 de AdventureWorksEntities que mapeia à função de modelo conceitual anterior.

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 anterior para exibir o rendimento de 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 modelo que retorna uma coleção (como um objeto de IQueryable<T> ). Considere a função do modelo conceitual abaixo dos retornos qualquer SalesOrderDetails para uma determinada identificação 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 de AdventureWorksEntities que mapeia à função de modelo conceitual anterior.

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 é retornado de IQueryable<T> mais refinados a linha de retorno totais 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 o definida como um método estático em uma classe personalizada

O exemplo a seguir demonstra como chamar uma função o definida como um método estático em uma classe personalizada. O exemplo usa o Modelo de Vendas do AdventureWorks.

Observação

Quando você chama uma função o definida como um método estático em uma classe personalizada, a função o definida deve aceitar uma coleção e retornar uma agregação dos valores na coleção.

Considere a função do modelo conceitual abaixo do rendimento do produto returns para uma coleção de SalesOrderDetail. (Para obter mais 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 os mapeamentos para o modelo conceitual funcionem anterior.

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 anterior para exibir o rendimento de produto para uma coleção de 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

Confira também