이 항목에서는 모델 정의 함수를 개체의 메서드 또는 사용자 지정 클래스의 ObjectContext 정적 메서드로 호출하는 방법에 대해 설명합니다. 모델 정의 함수는 개념적 모델에 정의된 함수입니다. 이 항목의 절차에서는 LINQ에서 엔터티 쿼리로 호출하는 대신 이러한 함수를 직접 호출하는 방법을 설명합니다. LINQ to Entities 쿼리에서 모델 정의 함수를 호출하는 방법에 대한 자세한 내용은 방법: 쿼리에서 Model-Defined 함수 호출을 참조하세요.
모델 정의 함수를 메서드로 ObjectContext 호출하든, 사용자 지정 클래스에서 정적 메서드로 호출하든, 먼저 메서드를 모델 정의 함수에 EdmFunctionAttribute매핑해야 합니다. 그러나 클래스에서 ObjectContext 메서드를 정의할 때는 속성을 사용하여 QueryProvider LINQ 공급자를 노출해야 하지만 사용자 지정 클래스에서 정적 메서드를 정의할 때는 이 속성을 사용하여 Provider LINQ 공급자를 노출해야 합니다. 자세한 내용은 아래 절차를 따르는 예제를 참조하세요.
아래 절차에서는 모델 정의 함수를 개체의 메서드로 호출하고 사용자 지정 클래스에서 ObjectContext 정적 메서드로 호출하기 위한 개략적인 개요를 제공합니다. 다음 예제에서는 절차의 단계에 대해 자세히 설명합니다. 프로시저는 개념적 모델에서 함수를 정의한 것으로 가정합니다. 자세한 내용은 방법: 개념 모델에서 사용자 지정 함수 정의를 참조하세요.
ObjectContext 개체에서 모델 정의 함수를 메서드로 호출하려면
Entity Framework 도구에서 자동으로 생성된 클래스에서 ObjectContext 파생된 부분 클래스를 확장하는 원본 파일을 추가합니다. 별도의 소스 파일에서 CLR 스텁을 정의하면 파일이 다시 생성될 때 변경 내용이 손실되지 않습니다.
다음을 수행하는 클래스에 ObjectContext CLR(공용 언어 런타임) 메서드를 추가합니다.
개념적 모델에 정의된 함수에 매핑합니다. 메서드를 매핑하려면 메서드에 EdmFunctionAttribute 적용해야 합니다. 특성의 NamespaceName 매개 변수 및 FunctionName 매개 변수는 각각 개념 모델의 네임스페이스 이름과 개념 모델의 함수 이름입니다. LINQ의 함수 이름 확인은 대/소문자를 구분합니다.
Execute 메서드가 속성 QueryProvider 에 의해 반환된 결과를 반환합니다.
클래스 인스턴스에서 메서드를 멤버로 호출합니다 ObjectContext .
사용자 지정 클래스에서 모델 정의 함수를 정적 메서드로 호출하려면
다음을 수행하는 정적 메서드를 사용하여 애플리케이션에 클래스를 추가합니다.
개념적 모델에 정의된 함수에 매핑합니다. 메서드를 매핑하려면 메서드에 EdmFunctionAttribute 적용해야 합니다. 특성의 NamespaceName 매개 변수 및 FunctionName 매개 변수는 각각 개념 모델의 네임스페이스 이름과 개념 모델의 함수 이름입니다.
인수를 IQueryable 수락합니다.
사용자 지정 클래스에서 정적 메서드를 멤버 메서드로 호출하십시오.
예제 1
ObjectContext 개체의 메서드로서 모델-정의 함수 호출
다음 예제에서는 모델 정의 함수를 개체의 메서드로 호출하는 ObjectContext 방법을 보여 줍니다. 이 예제에서는 AdventureWorks 판매 모델을 사용합니다.
지정된 제품에 대한 제품 수익을 반환하는 아래의 개념적 모델 함수를 고려합니다. (개념적 모델에 함수를 추가하는 방법에 대한 자세한 내용은 방법: 개념 모델에서 사용자 지정 함수 정의)를 참조하세요.
<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
사용자 지정 클래스에서 Model-Defined 함수를 정적 메서드로 호출
다음 예제에서는 사용자 지정 클래스에서 정적 메서드로 모델 정의 함수를 호출하는 방법을 보여 줍니다. 이 예제에서는 AdventureWorks 판매 모델을 사용합니다.
메모
모델 정의 함수를 사용자 지정 클래스에서 정적 메서드로 호출하는 경우 모델 정의 함수는 컬렉션을 수락하고 컬렉션의 값 집계를 반환해야 합니다.
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