Я пытаюсь создать класс стиля соглашения для Entity Framework Core 3 и немного озадачен сценарием обобщения. Я не использую DbSet<TEntity> SomeEntities { get; set; }
, скорее я создал базовый EntityDbContext, который предоставляет интерфейсы CQRS, а доступ к DbSets осуществляется с помощью dbContext.Set<TEntity>()
. Это означает, что у меня есть многоразовый DbContext во всех проектах, в которых я использую этот фреймворк, и это здорово, но это означает, что я должен время от времени думать по-разному. Я аннотирую свои классы сущностей с помощью пустого интерфейса IHistoryEnabled. В моем классе DbModelCreator я просматриваю загруженные сборки на предмет классов, реализующих IEfDbConvention, а затем вызываю SetConvention (...). В HistoryEnabledTableConvention мне просто нужно проверить, реализует ли сущность IHistoryEnabled, а затем вызвать:
modelBuilder.Entity<TEntity>(b => b.UseTemporalTable());
Это предоставляется библиотекой EntityFrameworkCore.TemporalTables . Поскольку это соглашение не имеет представления о типе, я не могу указать его напрямую как тип generi c. Кто-нибудь знает, как я могу вызвать показанный метод Entity, но с использованием типа, определенного во время выполнения? В качестве примера у меня есть класс сущности Employment : IHistoryEnabled
, а ClrType во время выполнения - 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(b => b.UseTemporalTable());
}
}
}
}
The full solution with a working example is здесь . Чтобы запустить его, просто протестируйте ExampleConsoleApp в качестве начального проекта.