다음을 통해 공유


방법: 생성된 데이터 개체 사용자 지정(Entity Framework)

이 항목에서는 생성된 데이터 클래스에 사용자 지정 메서드를 추가하는 방법을 보여 줍니다. 이 항목의 예제는 Adventure Works Sales 모델을 기반으로 합니다. 이 예제의 코드를 실행하려면 프로젝트에 AdventureWorks Sales 모델을 추가하고 Entity Framework를 사용하도록 프로젝트를 구성해야 합니다. 이렇게 하려면 방법: Entity Framework 프로젝트 수동 구성방법: 수동으로 모델 및 매핑 파일 정의(Entity Framework)의 절차를 수행합니다.

예제

이 예제에서는 생성된 SalesOrderHeader 클래스에 대한 사용자 지정 UpdateOrderTotal 메서드를 정의합니다. 이 사용자 지정 메서드는 세금, 운송료, 개별 항목 합계의 현재 값을 기반으로 TotalDue 속성을 업데이트합니다. 이 메서드는 Entity Framework 도구를 사용하여 SalesOrderHeader 클래스를 다시 생성할 때 손실되지 않도록 partial 클래스로 정의됩니다.

Partial Public Class SalesOrderHeader
        ' Update the order total. 
    Public Sub UpdateOrderTotal()
        Dim newSubTotal As Decimal = 0

        ' Ideally, this information is available in the EDM. 
        Dim taxRatePercent As Decimal = GetCurrentTaxRate()
        Dim freightPercent As Decimal = GetCurrentFreight()

        ' If the items for this order are loaded or if the order is 
        ' newly added, then recalculate the subtotal as it may have changed. 
        If Me.SalesOrderDetails.IsLoaded OrElse EntityState = EntityState.Added Then
            For Each item As SalesOrderDetail In Me.SalesOrderDetails
                ' Calculate line totals for loaded items. 
                newSubTotal += (item.OrderQty * (item.UnitPrice - item.UnitPriceDiscount))
            Next

            Me.SubTotal = newSubTotal
        End If

        ' Calculate the new tax amount. 
        Me.TaxAmt = Me.SubTotal + Decimal.Round((Me.SubTotal * taxRatePercent / 100), 4)

        ' Calculate the new freight amount. 
        Me.Freight = Me.SubTotal + Decimal.Round((Me.SubTotal * freightPercent / 100), 4)

        ' Calculate the new total. 
        Me.TotalDue = Me.SubTotal + Me.TaxAmt + Me.Freight
    End Sub
End Class
public partial class SalesOrderHeader
{
    // Update the order total.
    public void UpdateOrderTotal()
    {
        decimal newSubTotal = 0;

        // Ideally, this information is available in the EDM.
        decimal taxRatePercent = GetCurrentTaxRate();
        decimal freightPercent = GetCurrentFreight();

        // If the items for this order are loaded or if the order is 
        // newly added, then recalculate the subtotal as it may have changed.
        if (this.SalesOrderDetails.IsLoaded ||
            EntityState == EntityState.Added)
        {
            foreach (SalesOrderDetail item in this.SalesOrderDetails)
            {
                // Calculate line totals for loaded items.
                newSubTotal += (item.OrderQty *
                    (item.UnitPrice - item.UnitPriceDiscount));
            }

            this.SubTotal = newSubTotal;
        }

        // Calculate the new tax amount.
        this.TaxAmt = this.SubTotal
             + Decimal.Round((this.SubTotal * taxRatePercent / 100), 4);

        // Calculate the new freight amount.
        this.Freight = this.SubTotal
            + Decimal.Round((this.SubTotal * freightPercent / 100), 4);

        // Calculate the new total.
        this.TotalDue = this.SubTotal + this.TaxAmt + this.Freight;
    }
}

이 예제에서는 주문을 수정한 후 SalesOrderHeader의 사용자 지정 UpdateOrderTotal 메서드를 호출하여 TotalDue 속성을 업데이트합니다. SSDL(저장소 스키마 정의 언어) 파일에서 TotalDueStoreGeneratedPattern="computed" 특성이 적용되어 있으므로, 업데이트된 이 값은 SaveChanges 호출 시 서버에 저장되지 않습니다. 이 특성이 없는 경우 서버에서 계산된 열을 업데이트하면 UpdateException이 발생합니다.

Dim orderId As Integer = 43662

Using context As New AdventureWorksEntities()
    ' Return an order and its items. 
    Dim order As SalesOrderHeader = context.SalesOrderHeaders.Include("SalesOrderDetails") _
                                    .Where("it.SalesOrderID = @orderId", _
                                           New ObjectParameter("orderId", orderId)).First()

    Console.WriteLine("The original order total was: " & order.TotalDue)

    ' Update the order status. 
    order.Status = 1

    ' Increase the quantity of the first item, if one exists. 
    If order.SalesOrderDetails.Count > 0 Then
        order.SalesOrderDetails.First().OrderQty += 1
    End If

    ' Increase the shipping amount by 10%. 
    order.Freight = Decimal.Round(order.Freight * CDec(1.1), 4)

    ' Call the custom method to update the total. 
    order.UpdateOrderTotal()

    Console.WriteLine("The calculated order total is: " & order.TotalDue)

    ' Save changes in the object context to the database. 
    Dim changes As Integer = context.SaveChanges()

    ' Refresh the order to get the computed total from the store. 
    context.Refresh(RefreshMode.StoreWins, order)

    Console.WriteLine("The store generated order total is: " & order.TotalDue)
End Using
int orderId = 43662;

using (AdventureWorksEntities context =
    new AdventureWorksEntities())
{
    // Return an order and its items.
    SalesOrderHeader order =
        context.SalesOrderHeaders
        .Include("SalesOrderDetails")
        .Where("it.SalesOrderID = @orderId",
           new ObjectParameter("orderId", orderId)).First();

    Console.WriteLine("The original order total was: "
        + order.TotalDue);

    // Update the order status.
    order.Status = 1;

    // Increase the quantity of the first item, if one exists.
    if (order.SalesOrderDetails.Count > 0)
    {
        order.SalesOrderDetails.First().OrderQty += 1;
    }

    // Increase the shipping amount by 10%.
    order.Freight =
        Decimal.Round(order.Freight * (decimal)1.1, 4);

    // Call the custom method to update the total.
    order.UpdateOrderTotal();

    Console.WriteLine("The calculated order total is: "
        + order.TotalDue);

    // Save changes in the object context to the database.
    int changes = context.SaveChanges();

    // Refresh the order to get the computed total from the store.
    context.Refresh(RefreshMode.StoreWins, order);

    Console.WriteLine("The store generated order total is: "
        + order.TotalDue);
}

참고 항목

개념

개체 사용자 지정(Entity Framework)
비즈니스 논리 정의(Entity Framework)