I'm trying to create a convention style class for Entity Framework Core 3 and a little stumped on a generics scenario. I'm not using DbSet<TEntity> SomeEntities { get; set; }
, rather I've created a core EntityDbContext which provides CQRS interfaces and access to the DbSets is done with dbContext.Set<TEntity>()
. This means I have a reusable DbContext across all projects I use this framework with which is great, but it does mean I have to think differently from time to time.
So I have a requirement to provide Temporal Table support and I annotate my entity classes with an empty interface called IHistoryEnabled. In My DbModelCreator class I scan loaded assemblies for classes implementing IEfDbConvention and then call SetConvention(...). In the HistoryEnabledTableConvention I just need to check if the entity implements IHistoryEnabled and then call:
modelBuilder.Entity<TEntity>(b => b.UseTemporalTable());
That is provided by the library EntityFrameworkCore.TemporalTables. Because this convention has no idea aboout the type I can't specify it directly as a generic type. Does anyone know how I can actually invoke the Entity method shown but using a type determined at runtime? As an example I have an entity class Employment : IHistoryEnabled
and the ClrType at runtime is Employment
Here's the code as text for convenience:
public class HistoryEnabledTableConvention : IEfDbConvention
{
public void SetConvention(ModelBuilder modelBuilder)
{
foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
{
if (entityType.ClrType.GetInterfaces().ToList().Any(t => t.Name == nameof(IHistoryEnabled)))
{
// Need to replace this line...
modelBuilder.Entity<TEntity>(b => b.UseTemporalTable());
}
}
}
}
The full solution with a working example is here. To get it running just test the ExampleConsoleApp as the start project.
Aucun commentaire:
Enregistrer un commentaire