방법: 속성 변경 중 비즈니스 논리 실행(Entity Framework)

엔터티 프레임워크를 사용하면 생성된 속성이 변경될 때 사용자 지정 비즈니스 논리를 실행하여 사용자 지정 작업을 수행할 수 있습니다. EDM(엔터티 데이터 모델) 도구는 EDM에서 엔터티를 나타내는 데이터 클래스를 생성합니다. 이렇게 생성된 클래스를 직접 수정할 수는 없지만, 생성된 속성별로 이 도구는 OnPropertyChangingOnPropertyChanged라는 이름의 부분 메서드(Partial Method) 쌍도 생성합니다. 여기서 Property는 속성의 이름입니다. 이 메서드는 속성 변경 전후에 개체 서비스에 의해 호출되며, partial 데이터 클래스의 이러한 메서드를 확장하여 사용자 지정 코드를 구현할 수 있습니다. 생성된 클래스의 사용자 지정 방법에 대한 자세한 내용은 개체 사용자 지정(Entity Framework)을 참조하십시오.

이 항목의 예제는 Adventure Works Sales 모델을 기반으로 합니다. 이 예제의 코드를 실행하려면 프로젝트에 AdventureWorks Sales 모델을 추가하고 Entity Framework를 사용하도록 프로젝트를 구성해야 합니다. 이렇게 하려면 방법: Entity Framework 프로젝트 수동 구성방법: 엔터티 데이터 모델 수동 정의(Entity Framework)의 절차를 수행합니다.

속성 변경의 사용자 지정 유효성 검사를 구현하려면

  1. 프로젝트에서 유효성을 검사할 데이터 클래스별 사용자 지정 partial 클래스를 정의합니다.

  2. 이 partial 클래스에서 다음 메서드를 하나 또는 두 가지 모두 정의합니다. 여기서 Property는 유효성을 검사할 속성의 이름입니다.

    • OnPropertyChanging - 속성 유효성 검사와 같이 변경이 발생하기 전에 실행할 코드를 포함합니다. value 매개 변수는 속성이 변경되는 기준 값입니다. 속성 변경이 발생하기 전에 그 유효성을 검사하도록 이 메서드를 구현합니다. 변경이 수행되지 않게 하려면 예외를 throw해야 합니다.

    • OnPropertyChanged - 변경 기록과 같이 변경이 발생한 후 실행할 코드를 포함합니다.

예제

이 예제에서는 SalesOrderDetail.OrderQty가 변경되기 전에 주문 변경이 가능한지 그리고 보류 중인 변경이 파일에 기록되어 있는지 확인하기 위해 SalesOrderHeader.Status의 값을 확인합니다. 이 작업은 OnOrderQtyChanging 부분 메서드(Partial Method)에서 수행됩니다. 변경을 수행할 수 없는 경우 예외가 발생합니다. 그런 다음 변경이 성공적으로 수행되면 SalesOrderHeader.Status 값은 1로 재설정되며 완료된 변경이 기록됩니다. 이 작업은 OnOrderQtyChanged 부분 메서드(Partial Method)에서 수행됩니다.

Partial Public Class SalesOrderDetail
    Inherits EntityObject
    Private Sub OnOrderQtyChanging(ByVal value As Short)
        ' Only handle this change for existing SalesOrderHeader 
        ' objects that are attached to an object context. If the item
        ' is detached then we cannot access or load the related order.
        If EntityState <> EntityState.Detached Then
            Try
                ' Ensure that the referenced SalesOrderHeader is loaded.
                If Not SalesOrderHeaderReference.IsLoaded Then
                    SalesOrderHeaderReference.Load()
                End If

                Dim order As SalesOrderHeader = SalesOrderHeader

                ' Cancel the change if the order cannot be modified.
                If SalesOrderHeader.Status > 3 Then
                    Throw New ApplicationException("The quantity cannot be changed " _
                    + "or the item cannot be added because the order has either " _
                    + "already been shipped or has been cancelled.")
                End If

                ' Log the pending order change.
                File.AppendAllText(LogFile, "Quantity of item '" _
                    + SalesOrderDetailID.ToString() + "' in order '" _
                    + order.SalesOrderID.ToString() _
                    + "' changing from '" + OrderQty.ToString() _
                    + "' to '" + value.ToString() + "'." + Environment.NewLine _
                    + "Change made by user: " + Environment.UserName _
                    + Environment.NewLine)
            Catch ex As InvalidOperationException
                Throw New ApplicationException("The quantity could not be changed " _
                + " because the order information could not be retrieved. " _
                + "The following error occurred:" + ex.Message)
            End Try
        End If
    End Sub
    Private Sub OnOrderQtyChanged()
        ' Only handle this change for existing SalesOrderHeader 
        ' objects that are attached to an object context.
        If EntityState <> EntityState.Detached Then
            Try
                ' Ensure that the SalesOrderDetail is loaded.
                If Not SalesOrderHeaderReference.IsLoaded Then
                    SalesOrderHeaderReference.Load()
                End If

                ' Reset the status for the order related to this item.
                SalesOrderHeader.Status = 1

                ' Log the completed order change.
                File.AppendAllText(LogFile, "Quantity of item '" _
                    + SalesOrderDetailID.ToString() + "' in order '" _
                    + SalesOrderHeader.SalesOrderID.ToString() _
                    + "' successfully changed to '" + OrderQty.ToString() _
                    + "'." + Environment.NewLine _
                    + "Change made by user: " + Environment.UserName _
                    + Environment.NewLine)
            Catch ex As InvalidOperationException
                Throw New ApplicationException("An error occurred " _
                + "the data could be in an inconsistent state. " _
                + Environment.NewLine + ex.Message)
            End Try
        End If
    End Sub
End Class
public partial class SalesOrderDetail : EntityObject
{
    partial void OnOrderQtyChanging(short value)
    {
        // Only handle this change for existing SalesOrderHeader 
        // objects that are attached to an object context. If the item
        // is detached then we cannot access or load the related order.
        if (EntityState != EntityState.Detached)
        {
            try
            {
                // Ensure that the referenced SalesOrderHeader is loaded.
                if (!this.SalesOrderHeaderReference.IsLoaded)
                {
                    this.SalesOrderHeaderReference.Load();
                }

                // Cancel the change if the order cannot be modified.
                if (this.SalesOrderHeader.Status > 3)
                {
                    throw new ApplicationException("The quantity cannot be changed "
                    + "or the item cannot be added because the order has either "
                    + "already been shipped or has been cancelled.");
                }

                // Log the pending order change.
                File.AppendAllText(LogFile, "Quantity of item '"
                    + this.SalesOrderDetailID.ToString() + "' in order '"
                    + this.SalesOrderHeader.SalesOrderID.ToString()
                    + "' changing from '" + this.OrderQty.ToString()
                    + "' to '" + value.ToString() + "'." + Environment.NewLine
                    + "Change made by user: " + Environment.UserName
                    + Environment.NewLine);
            }
            catch (InvalidOperationException ex)
            {
                throw new ApplicationException("The quantity could not be changed "
                + " because the order information could not be retrieved. "
                + "The following error occurred:" + ex.Message);
            }
        }
    }
    partial void OnOrderQtyChanged()
    {
        // Only handle this change for existing SalesOrderHeader 
        // objects that are attached to an object context.
        if (EntityState != EntityState.Detached)
        {
            try
            {
                // Ensure that the SalesOrderDetail is loaded.
                if (!SalesOrderHeaderReference.IsLoaded)
                {
                    SalesOrderHeaderReference.Load();
                }

                // Reset the status for the order related to this item.
                this.SalesOrderHeader.Status = 1;

                // Log the completed order change.
                File.AppendAllText(LogFile, "Quantity of item '"
                    + SalesOrderDetailID.ToString() + "' in order '"
                    + SalesOrderHeader.SalesOrderID.ToString()
                    + "' successfully changed to '" + OrderQty.ToString()
                    + "'." + Environment.NewLine
                    + "Change made by user: " + Environment.UserName
                    + Environment.NewLine);
            }
            catch (InvalidOperationException ex)
            {
                throw new ApplicationException("An error occurred; "
                + "the data could be in an inconsistent state. "
                + Environment.NewLine + ex.Message);
            }
        }
    }
}

참고 항목

기타 리소스

엔터티 데이터 모델 도구