Sto lavorando a un progetto .NET Core usando entity framework core (2.0.1).
Dispongo di un'architettura plug-in che richiede il caricamento di modelli diversi in base ai plug-in allegati, quindi provando a caricare dinamicamente i modelli quando si aggiunge dbcontext al contenitore DI utilizzando il metodo DbContextOptionsBuilder.UseModel.
Indipendentemente se definisco un nuovo modello o un ModelBuilder, gli EntityTypes che sto aggiungendo non sembrano farlo correttamente e una volta aggiunto a dbcontext non sembra avere alcuna proprietà.
Non sono sicuro che ci sia una convenzione che devo aggiungere perché funzioni o che mi manchi. Qualsiasi aiuto sarebbe apprezzato.
_services.AddDbContext<DataContext>(options =>
{
switch (_config.DatabaseType.ToLower())
{
case "postgres":
options.UseNpgsql(_config.ConnectionString);
break;
case "sqlserver":
options.UseSqlServer(_config.ConnectionString);
break;
}
var convention = new Microsoft.EntityFrameworkCore.Metadata.Conventions.ConventionSet();
var mb = new ModelBuilder(convention);
foreach (var definition in definitionList)
{
mb.Entity(definition.Type);
}
options.UseModel(mb.Model);
});
Risolve in:
Crea correttamente i 5 EntityTypes, ma una volta che espongo uno dei tipi di entità non ha proprietà.
Se faccio lo stesso usando la convenzione standard di aggiungere EntityType tramite l'override di onbodelbuilding di dbcontext, le proprietà sono tutte lì correttamente ...
Sì, ci sono alcune convenzioni di default , una delle quali è una PropertyDiscoveryConvention
che suona come se si assicurasse che tutte le proprietà vengano aggiunte di default, ma anche altre probabilmente importanti come una KeyDiscoveryConvention
e molte convenzioni che si occupano di identificare gli attributi di mappatura.
Probabilmente potresti assicurarti di creare le giuste convenzioni, ma potrebbe essere più semplice spostare la logica nel contesto del database. In questo modo puoi costruire su tutte le convenzioni standard, come si farebbe normalmente, e non avrai bisogno di prenderti cura di te stesso. Quindi forse qualcosa del genere:
class MyContext : DbContext
{
private readonly IDbContextConfigurator _dbContextConfigurator;
public MyContext(DbOptions<MyContext> dbOptions, IDbContextConfigurator dbContextConfigurator)
: base(dbOptions)
{
_dbContextConfigurator = dbContextConfigurator;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
_dbContextConfigurator.Configure(modelBuilder);
}
}
Quindi all'interno di IDbContextConfigurator
è quindi possibile recuperare la configurazione e configurare il modello direttamente sul generatore di modelli.