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à.

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

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.
Tags:
C#236 Entity framework4 Esempi225
Potrebbe interessarti anche: