スカラー プロパティの変更時にビジネス ロジックを実行する方法 (Entity Framework)

Entity Framework では、カスタム ビジネス ロジックを実行することによって、生成されたプロパティが変更されたときにカスタム アクションを実行できます。 Entity Data Model  ツールは、概念モデルのエンティティを表すデータ クラスを生成します。 生成されたクラスを直接変更することはできませんが、生成されるプロパティごとに、OnPropertyChanging および OnPropertyChanged という部分メソッドのペアも生成されます (Property はプロパティ名)。 これらのメソッドは、プロパティ変更の前後に Entity Framework によって呼び出されます。これらのメソッドを部分データ クラスで拡張すると、カスタム コードを実装できます。

Cc716747.note(ja-jp,VS.100).gif注 :
オブジェクトレイヤー コードが、既定のテキスト テンプレート以外のテキスト テンプレートを使用して生成された場合、部分メソッドが生成されていない可能性があります。

このトピックの例では、Adventure Works Sales Model が使用されています。 この例のコードを実行するには、あらかじめプロジェクトに AdventureWorks Sales Model を追加し、Entity Framework が使用されるようにプロジェクトを構成しておく必要があります。 具体的な方法については、「Entity Framework プロジェクトを手動で構成する方法」および「方法: モデル ファイルとマッピング ファイルを手動で定義する (Entity Framework)」の手順を参照してください。

プロパティの変更に関するカスタム検証を実装するには

  1. プロジェクトで、検証するデータ クラスごとにカスタム部分クラスを 1 つ定義します。

  2. この部分クラスで、次のメソッドのいずれかまたは両方を定義します。Property は、検証するプロパティの名前です。

    • On Property Changing - プロパティを変更する前に実行するコードを入力します (プロパティの検証など)。 value パラメーターは、変更後のプロパティの値です。 このメソッドを実装すると、プロパティ変更の前にプロパティが検証されるようになります。 変更が加えられるのを防ぐには、例外をスローする必要があります。

    • On Property Changed - プロパティを変更した後で実行するコードを入力します (変更のログなど)。

この例では、SalesOrderDetail.OrderQty を変更する前に SalesOrderHeader.Status の値をチェックすることによって順序を変更できることが確認され、保留中の変更がファイルに記録されます。 このアクションは、部分メソッド 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 Me.SalesOrderHeaderReference.IsLoaded Then
                    Me.SalesOrderHeaderReference.Load()
                End If

                ' Cancel the change if the order cannot be modified. 
                If Me.SalesOrderHeader.Status > 3 Then
                    Throw New InvalidOperationException("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 '" & _
                    Me.SalesOrderDetailID.ToString() & "' in order '" & _
                    Me.SalesOrderHeader.SalesOrderID.ToString() & _
                    "' changing from '" + Me.OrderQty.ToString() & _
                    "' to '" & value.ToString() + "'." & Environment.NewLine & _
                    "Change made by user: " & Environment.UserName & _
                    Environment.NewLine)
            Catch ex As InvalidOperationException
                Throw New InvalidOperationException(("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. 
                Me.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 InvalidOperationException(("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 InvalidOperationException("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 InvalidOperationException("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 InvalidOperationException("An error occurred; "
                + "the data could be in an inconsistent state. "
                + Environment.NewLine + ex.Message);
            }
        }
    }
}

参照

処理手順

方法: オブジェクト状態が変化したときにビジネス ロジックを実行する
方法: アソシエーションの変更時にビジネス ロジックを実行する
変更を保存するときにビジネス ロジックを実行する方法 (Entity Framework)

その他のリソース

Entity Data Model Tools