共用方式為


HOW TO:在屬性變更期間執行商務邏輯 (Entity Framework)

實體架構 可讓您在變更產生的屬性之前,先執行自訂商務邏輯來執行自訂動作。 實體資料模型 (EDM) 工具會產生代表 EDM 中之實體的資料類別。 雖然不應該針對每一個產生的屬性直接修改這些產生的類別,不過工具也會產生一對名為 OnPropertyChangingOnPropertyChanged 的部分方法,其中 Property 是屬性名稱。 這些方法會在變更屬性的前後由物件服務所呼叫,而且您可以在部分資料類別中擴充這些方法來實作自訂程式碼。 如需如何自訂產生之類別的詳細資訊,請參閱自訂物件 (Entity Framework)

本主題的範例是根據 Adventure Works Sales Model。 若要執行此範例中的程式碼,您必須已經將 AdventureWorks Sales Model 加入到專案中,並設定您的專案使用 Entity Framework。 若要這樣做,請完成 HOW TO:手動設定 Entity Framework 專案HOW TO:以手動方式定義 Entity Data Model (Entity Framework) 中的程序。

若要針對屬性變更實作自訂驗證

  1. 在您的專案中,針對每一個要驗證的資料類別定義自訂部分類別。

  2. 在此部分類別中,定義下列其中一個或兩個方法,其中 Property 是要驗證的屬性名稱:

    • OnPropertyChanging - 包含變更發生之前所要執行的程式碼,例如屬性驗證。 value 參數是屬性要變更成的值。 請實作這個方法,在屬性變更發生之前進行驗證。 若要避免變更的進行,您必須擲回例外狀況。

    • OnPropertyChanged - 包含變更發生之後所要執行的程式碼,例如記錄變更。

範例

這個範例會檢查 SalesOrderHeader.Status 的值,以確定在變更 SalesOrderDetail.OrderQty 之前可以變更訂單,而且暫止的變更會記錄到檔案中。 這個動作會在 OnOrderQtyChanging 部分方法中執行。 如果無法進行變更,便會引發例外狀況。 因此,在成功進行變更之後,SalesOrderHeader.Status 值會重設為 1,而且會記錄完成的變更。 這些動作會在 OnOrderQtyChanged 部分方法中執行。

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

另請參閱

其他資源

Entity Data Model 工具