Entity Framework: salvare automaticamente la data di ultima modifica
Spesso torna utile avere nelle tabelle del database dei campi che tengono traccia della data di creazione e ultima modifica, oltre all'utente che ha effettuato la creazione e l'ultima modifica del record.
Con Entity Framework 4 è possibile automatizzare queste operazioni in modo da non doverle fare (ricordarsi) ad ogni cambiamento dell'oggetto. La classe di mapping che viene creata dal designer (in questo caso Sgart.Data.Sgart_Entities) è una partial ed è quindi possibile creare un file separato per aggiungere del codice a questa classe.
Per ottenere il salvataggio automatico, implemento il metodo OnContextCreated, invocato ad ogni creazione del contesto. Su questo metodo vado ad aggiungere un handler all'evento SavingChanges, quest'ultimo è richiamato ogni volta che si invoca il metodo SaveChange del contesto.
In pratica ciclo su tutti gli oggetti modificati e/o aggiunti e, se esistono, setto le corrispondenti proprietà.
Allo stesso modo potrei andare ad impostare altri campi come ad esempio la chiave di un oggetto di tipo Guid. A questo proposito vedi Entity Framework: valorizzare automaticamente i campi Identity di tipo Guid
Con Entity Framework 4 è possibile automatizzare queste operazioni in modo da non doverle fare (ricordarsi) ad ogni cambiamento dell'oggetto. La classe di mapping che viene creata dal designer (in questo caso Sgart.Data.Sgart_Entities) è una partial ed è quindi possibile creare un file separato per aggiungere del codice a questa classe.
Per ottenere il salvataggio automatico, implemento il metodo OnContextCreated, invocato ad ogni creazione del contesto. Su questo metodo vado ad aggiungere un handler all'evento SavingChanges, quest'ultimo è richiamato ogni volta che si invoca il metodo SaveChange del contesto.
In pratica ciclo su tutti gli oggetti modificati e/o aggiunti e, se esistono, setto le corrispondenti proprietà.
C#: Sgart_Entities_Extension.cs
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data.EntityClient;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Runtime.Serialization;
namespace Sgart.Data
{
public partial class Sgart_Entities
{
private const string MODIFIEDBY = "ModifiedBy";
private const string MODIFIED = "Modified";
private const string CREATEDBY = "CreatedBy";
private const string CREATED = "Created";
private const string DEFAULTUSER = "Anonymous";
partial void OnContextCreated()
{
this.SavingChanges += new EventHandler(Internal_SavingChanges);
}
private void Internal_SavingChanges(object sender, EventArgs e)
{
ObjectContext context = (ObjectContext)sender;
IEnumerable<ObjectStateEntry> changes = context.ObjectStateManager.GetObjectStateEntries(
System.Data.EntityState.Added | System.Data.EntityState.Modified);
DateTime dt = DateTime.Now;
string loginName = string.IsNullOrEmpty(System.Web.HttpContext.Current.User.Identity.Name)
? DEFAULTUSER
: System.Web.HttpContext.Current.User.Identity.Name;
foreach (ObjectStateEntry entry in changes)
{
CurrentValueRecord records = entry.CurrentValues;
for (int i = 0; i < records.FieldCount; i++)
{
string name = records.GetName(i);
switch (name)
{
case MODIFIEDBY:
records.SetString(i, loginName);
break;
case MODIFIED:
records.SetDateTime(i, dt);
break;
}
if (entry.State == System.Data.EntityState.Added)
{
switch (name)
{
case CREATEDBY:
records.SetString(i, loginName);
break;
case CREATED:
records.SetDateTime(i, dt);
break;
}
}
}
}
}
}
}
Attenzione, se usi l'oggetto EntityDataSource da designer devi ricordarti di settare la proprietà ContextTypeName con il nome completo della classe, in questo caso Sgart.Data.Sgart_Entities, altrimenti l'evento SavingChanges non viene invocato.