Procedura: eseguire la logica di business quando vengono modificate le proprietà scalari (Entity Framework)
Entity Framework consente di eseguire logica di business personalizzata per eseguire azioni personalizzate quando vengono apportate modifiche alle proprietà generate. Tramite gli strumenti Entity Data Model vengono generate classi di dati che rappresentano entità in un modello concettuale. Sebbene queste classi generate non possano essere modificate direttamente, per ogni proprietà generata gli strumenti generano anche una coppia di metodi parziali denominati OnproprietàChanging e OnproprietàChanged, dove proprietà è il nome della proprietà. Questi metodi vengono chiamati da Entity Framework prima e dopo la modifica di una proprietà e possono essere estesi nelle classi di dati parziali per implementare codice personalizzato.
Nota: |
---|
Se il codice del livello oggetti è stato generato con un modello di testo diverso da un modello di testo predefinito, i metodi parziali potrebbero non essere stati generati. |
L'esempio incluso in questo argomento è basato sul modello Sales di AdventureWorks. Per eseguire il codice incluso in questo esempio, è necessario avere già aggiunto il modello Sales di AdventureWorks al progetto e avere configurato il progetto per l'utilizzo di Entity Framework. A tale scopo, completare le procedure descritte in Procedura: configurare manualmente un progetto di Entity Framework e Procedura: definire manualmente i file di modello e di mapping (Entity Framework).
Per implementare la convalida personalizzata per le modifiche alle proprietà
Nel progetto definire una classe parziale personalizzata per ogni classe di dati da convalidare.
In questa classe parziale definire uno dei metodi seguenti, o entrambi i metodi, dove Proprietà è il nome della proprietà da convalidare:
On Proprietà Changing: includere il codice da eseguire prima della modifica, ad esempio la convalida della proprietà. Il parametro value rappresenta il valore che viene impostato per la proprietà modificata. Implementare questo metodo per convalidare una modifica a una proprietà prima che venga eseguita. Per impedire che vengano apportate modifiche, è necessario generare un'eccezione.
On Proprietà Changed: includere il codice da eseguire dopo la modifica, ad esempio la registrazione della modifica.
Esempio
In questo esempio viene controllato il valore di SalesOrderHeader.Status per verificare che l'ordine possa essere modificato prima di apportare la modifica a SalesOrderDetail.OrderQty e la modifica in sospeso viene registrata in un file. Questa azione viene eseguita nel metodo parziale OnOrderQtyChanging. Se non è possibile apportare la modifica, viene generata un'eccezione. Dopo che la modifica è stata apportata, il valore di SalesOrderHeader.Status viene quindi reimpostato su 1 e la modifica completata viene registrata. Queste azioni vengono eseguite nel metodo parziale 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);
}
}
}
}
Vedere anche
Attività
Procedura: eseguire la logica di business al momento della modifica dello stato dell'oggetto (Entity Framework)
Procedura: eseguire la logica di business quando vengono modificate le associazioni
Procedura: eseguire la logica di business al momento del salvataggio delle modifiche (Entity Framework)