다음을 통해 공유


방법: 개체 메서드로 모델 정의 함수 호출

이 항목에서는 모델 정의 함수를 ObjectContext 개체의 메서드 또는 사용자 지정 클래스의 정적 메서드로 호출하는 방법에 대해 설명합니다. 모델 정의 함수는 개념적 모델에 정의되는 함수입니다. 이 항목의 절차에서는 이러한 함수를 LINQ to Entities 쿼리에서 호출하는 대신 직접 호출하는 방법에 대해 설명합니다. LINQ to Entities 쿼리에서 모델 정의 함수를 호출하는 방법에 대한 자세한 내용은 방법: 쿼리에서 모델 정의 함수 호출을 참조하세요.

모델 정의 함수를 ObjectContext 메서드 또는 사용자 지정 클래스의 정적 메서드로 호출하려면 먼저 메서드를 EdmFunctionAttribute가 있는 모델 정의 함수로 매핑해야 합니다. 그러나 ObjectContext 클래스의 메서드를 정의하는 경우에는 QueryProvider 속성을 사용하여 LINQ 공급자를 노출해야 하고, 사용자 지정 클래스의 정적 메서드를 정의하는 경우에는 Provider 속성을 사용하여 LINQ 공급자를 노출해야 합니다. 자세한 내용은 다음 절차 아래에 나오는 예제를 참조하세요.

다음 절차에서는 모델 정의 함수를 ObjectContext 개체의 메서드 및 사용자 지정 클래스의 정적 메서드로 호출하는 방법에 대해 간단히 설명합니다. 절차 다음에 나오는 예제에서는 절차의 단계를 보다 자세히 설명합니다. 이러한 절차에서는 사용자가 개념적 모델에서 함수를 정의했다고 가정합니다. 자세한 내용은 방법: 개념적 모델에서 사용자 지정 함수 정의를 참조하세요.

모델 정의 함수를 ObjectContext 개체의 메서드로 호출하려면

  1. Entity Framework 도구에 의해 자동으로 생성된 ObjectContext 클래스에서 파생되는 partial 클래스를 확장하기 위해 소스 파일을 추가합니다. CLR 스텁을 별도의 소스 파일에서 정의하면 파일을 다시 생성할 때 변경 내용이 손실되지 않습니다.

  2. 다음 작업을 수행하는 ObjectContext 클래스에 CLR(공용 언어 런타임) 메서드를 추가합니다.

    • 개념적 모델에 정의된 함수로 매핑합니다. 메서드를 매핑하려면 메서드에 EdmFunctionAttribute를 적용해야 합니다. 특성의 NamespaceName 매개 변수는 개념적 모델의 네임스페이스 이름이고, 특성의 FunctionName 매개 변수는 개념적 모델의 함수 이름입니다. LINQ에서 함수 이름을 확인할 때는 대/소문자가 구분됩니다.

    • Execute 속성에 의해 반환된 QueryProvider 메서드의 결과를 반환합니다.

  3. 메서드를 ObjectContext 클래스 인스턴스의 멤버로 호출합니다.

모델 정의 함수를 사용자 지정 클래스의 정적 메서드로 호출하려면

  1. 다음 작업을 수행하는 정적 메서드가 포함된 애플리케이션에 클래스를 추가합니다.

    • 개념적 모델에 정의된 함수로 매핑합니다. 메서드를 매핑하려면 메서드에 EdmFunctionAttribute를 적용해야 합니다. 특성의 NamespaceName 매개 변수는 개념적 모델의 네임스페이스 이름이고, 특성의 FunctionName 매개 변수는 개념적 모델의 함수 이름입니다.

    • IQueryable 인수를 받아들입니다.

    • Execute 속성에 의해 반환된 Provider 메서드의 결과를 반환합니다.

  2. 메서드를 사용자 지정 클래스의 정적 메서드 멤버로 호출합니다.

예 1

모델 정의 함수를 ObjectContext 개체의 메서드로 호출

다음 예제에서는 모델 정의 함수를 ObjectContext 개체의 메서드로 호출하는 방법에 대해 설명합니다. 이 예제에서는 AdventureWorks Sales 모델을 사용합니다.

지정된 제품의 제품 수익을 반환하는 다음 개념적 모델 함수를 살펴보세요. (개념적 모델에 함수를 추가하는 방법에 대한 자세한 내용은 방법: 개념적 모델에서 사용자 지정 함수 정의를 참조하세요.)

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

예제 2

다음 코드에서는 위의 개념적 모델 함수로 매핑되는 AdventureWorksEntities 클래스에 메서드를 추가합니다.

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

예 3

다음 코드에서는 위의 메서드를 호출하여 지정된 제품의 제품 수익을 표시합니다.

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

예시 4

다음 예제에서는 컬렉션을 반환하는 모델 정의 함수를 IQueryable<T> 개체로 호출하는 방법에 대해 설명합니다. 제공된 제품 ID의 모든 SalesOrderDetails를 반환하는 다음 개념적 모델 함수를 살펴보세요.

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

예제 5

다음 코드에서는 위의 개념적 모델 함수로 매핑되는 AdventureWorksEntities 클래스에 메서드를 추가합니다.

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

예제 6

다음 코드에서는 메서드를 호출합니다. 반환된 IQueryable<T> 쿼리는 각 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

예제 7

모델 정의 함수를 사용자 지정 클래스의 정적 메서드로 호출

다음 예제에서는 모델 정의 함수를 사용자 지정 클래스의 정적 메서드로 호출하는 방법에 대해 설명합니다. 이 예제에서는 AdventureWorks Sales 모델을 사용합니다.

참고 항목

모델 정의 함수를 사용자 지정 클래스의 정적 메서드로 호출할 때 모델 정의 함수는 컬렉션을 받아들이고 컬렉션의 값 집계를 반환해야 합니다.

SalesOrderDetail 컬렉션의 제품 수익을 반환하는 다음 개념적 모델 함수를 살펴보세요. (개념적 모델에 함수를 추가하는 방법에 대한 자세한 내용은 방법: 개념적 모델에서 사용자 지정 함수 정의를 참조하세요.)

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

예제 8

다음 코드에서는 위의 개념적 모델 함수로 매핑되는 정적 메서드가 포함된 애플리케이션에 클래스를 추가합니다.

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

예제 9

다음 코드에서는 위의 메서드를 호출하여 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

참고 항목