Versione dopo versione, il team di EF ha aggiunto diversi punti di estensione per intercettare eventi nel momento in cui questi si verificano. I primi punti di intercettazione sono stati quelli che si inserivano nella pipeline di esecuzione del codice SQL. Successivamente si sono aggiunti eventi per la fase di aggiunta e rimozione delle entity dal meccanismo di tracking e per la fase precedente e successiva alla persistenza sul database.
Entity Framework 7 introduce nuovi punti di estensione tra cui quello relativo alla materializzazione delle entity. La materializzazione è il processo di creazione dell'entity e il successivo popolamento delle proprietà partendo dai dati provenienti dalle query fatte al database. Se vogliamo personalizzare il processo di materializzazione, dobbiamo creare un interceptor che implementa l'interfaccia IMaterializationInterceptor e implementare almeno uno dei metodi dell'interfaccia (che fornisce già un'implementazione di base).
- CreatingInstance: invocato prima di istanziare l'entity. Implementando questo metodo possiamo creare noi l'entity scartando l'istanza creata da EF. Torna utile quando vogliamo usare una factory per creare le entity;
- CreatedInstance: invocato dopo che l'entity è stata istanziata;
- InitializingInstance: invocato prima di popolare le proprietà dell'entity;
- InitializedInstance: invocato dopo aver popolato le proprietà dell'entity;
Supponiamo di dover mantenere nelle entity la data di materializzazione dal database, in questo caso possiamo far implementare un'interfaccia alle entity e nel metodo InitializedInstanze verificare che se l'entity materializzata implementa quell'interfaccia allora andiamo a popolare la data di materializzazione.
public interface IHasMaterializationDate { DateTime MaterializationDate { get; set; } } public class Person : IHasMaterializationDate { public int Id { get; set; } public string Name { get; set; } = null!; [NotMapped] public DateTime MaterializationDate { get; set; } } public class MaterializationDateInterceptor : IMaterializationInterceptor { public object InitializedInstance(MaterializationInterceptionData materializationData, object instance) { if (instance is IHasMaterializationDate hasMaterializationDate) { hasMaterializationDate.MaterializationDate = DateTime.UtcNow; } return instance; } }
Una volta creato l'interceptor, non ci resta che aggiungerlo alla lista degli interceptor in fase di configurazione utilizzando le API di EF già esistenti.
public class PeopleContext : DbContext { private static readonly MaterializationDateInterceptor _materializationDateInterceptor = new(); public DbSet<Person> People => Set<Person>(); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .AddInterceptors(_materializationDateInterceptor) .UseSqlServer(connectionstring); }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Aprire una finestra di dialogo per selezionare una directory in WPF e .NET 8
Usare il colore CSS per migliorare lo stile della pagina
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Eseguire una GroupBy per entity in Entity Framework
Eseguire attività pianificate con Azure Container Jobs
Migrare una service connection a workload identity federation in Azure DevOps
Utilizzare Tailwind CSS all'interno di React: primi componenti
Utilizzare Copilot con Azure Cosmos DB
Cambiare la chiave di partizionamento di Azure Cosmos DB
Limitare le richieste lato server con l'interactive routing di Blazor 8
Usare lo spread operator con i collection initializer in C#
Modificare i metadati nell'head dell'HTML di una Blazor Web App