다음을 통해 공유


방법: 모델 정의 함수를 개체 메서드로 호출(LINQ to Entities)

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

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

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

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

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

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

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

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

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

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

  1. 다음 작업을 수행하는 정적 메서드가 포함된 응용 프로그램에 클래스를 추가합니다.

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

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

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

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

예제

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

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

지정된 제품의 제품 수익을 반환하는 다음 개념적 모델 함수를 살펴보십시오. 개념적 모델에 함수를 추가하는 방법은 How to: Define Custom Functions in the Conceptual Model를 참조하십시오.

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

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

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
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))));
    }
}

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

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
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    Console.WriteLine(AWEntities.GetProductRevenue(productId));
}

다음 예제에서는 컬렉션을 반환하는 모델 정의 함수를 IQueryable 개체로 호출하는 방법에 대해 설명합니다. 제공된 제품 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>

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

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
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))));
    }
}

다음 코드에서는 메서드를 호출합니다. 반환된 IQueryable 쿼리는 각 SalesOrderDetail의 품목 합계를 반환하도록 보다 구체화됩니다.

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
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);
    }
}

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

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

Dd456845.note(ko-kr,VS.100).gif참고:
모델 정의 함수를 사용자 지정 클래스의 정적 메서드로 호출할 때 모델 정의 함수는 컬렉션을 받아들이고 컬렉션의 값 집계를 반환해야 합니다.

SalesOrderDetail 컬렉션의 제품 수익을 반환하는 다음 개념적 모델 함수를 살펴보십시오. 개념적 모델에 함수를 추가하는 방법은 How to: Define Custom Functions in the Conceptual Model를 참조하십시오.

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

다음 코드에서는 위의 개념적 모델 함수로 매핑되는 정적 메서드가 포함된 응용 프로그램에 클래스를 추가합니다.

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
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>))));
    }
}

다음 코드에서는 위의 메서드를 호출하여 SalesOrderDetail 컬렉션의 제품 수익을 표시합니다.

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
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));
}

참고 항목

개념

LINQ to Entities의 쿼리
LINQ to Entities 쿼리의 함수 호출

기타 리소스

.edmx File Overview