Поделиться через


Как выполнить бизнес-логику при изменении свойств (платформа Entity Framework)

Entity Framework позволяет выполнять собственную пользовательскую бизнес-логику для выполнения пользовательских действий в том случае, если в сформированные свойства были внесены изменения. Средства модели Entity Data Model (модель EDM) формируют классы данных, представляющие сущности в модели EDM. Хотя эти сформированные классы нельзя изменять напрямую, но для каждого из них средства формируют пару разделяемых методов с именами OnСвойствоChanging и OnСвойствоChanged, где Свойство — имя свойства. Данные методы вызываются службами объектов до и после изменения свойства; данные методы можно расширить в разделяемых классах данных для реализации пользовательского кода. Дополнительные сведения о настройках формируемых классов см. в разделе Настройка объектов (платформа Entity Framework).

Пример в этом разделе основан на модели Adventure Works Sales. Чтобы запустить код, используемый в данном примере, нужно сначала добавить к проекту модель AdventureWorks Sales и настроить его для использования платформы Entity Framework. Для этого выполните инструкции из разделов Как вручную настроить проект Entity Framework и Как определить модель EDM вручную (платформа Entity Framework).

Реализация пользовательской проверки изменений свойств

  1. В проекте определите пользовательский разделяемый класс для каждого проверяемого класса данных.

  2. В этом разделяемом классе определите один или оба следующих метода (Свойство — это имя проверяемого свойства):

    • OnСвойствоChanging — включает код, который будет выполняться перед выполнением изменения, например проверка свойства. Параметр value — это значение, на которое заменяется свойство. Реализуйте данный метод, чтобы выполнять проверку изменения свойства перед его выполнением. Чтобы предотвратить выполнение изменения, следует вызвать исключение.

    • OnСвойствоChanged — включает код, который будет выполняться после выполнения изменения, например внесение изменения в журнал.

Примеры

В этом примере проверяется значение 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);
            }
        }
    }
}

См. также

Другие ресурсы

Средства работы с моделью EDM