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
Ottenere un token di accesso per una GitHub App
Migrare una service connection a workload identity federation in Azure DevOps
Registrare servizi multipli tramite chiavi in ASP.NET Core 8
Utilizzare Copilot con Azure Cosmos DB
Gestire il colore CSS con HWB
Creare un webhook in Azure DevOps
Aggiungere interattività lato server in Blazor 8
Code scanning e advanced security con Azure DevOps
Recuperare l'ultima versione di una release di GitHub
Utilizzare il trigger SQL con le Azure Function
Aprire una finestra di dialogo per selezionare una directory in WPF e .NET 8
Creare una libreria CSS universale: Cards