我正在开发一个应用程序,它可以通过使用MEF的插件进行扩展。该应用程序正在使用实体框架。上下文由工厂方法创建:
public class DataContextFactory
{
[ImportingConstructor]
public DataContextFactory([ImportMany] IEnumerable<IModelCreator> modelCreators, [Import(AllowDefault = true)]IDatabaseInitializer<DataContext> initializer)
{
ModelCreators = modelCreators;
Initializer = initializer ?? new DefaultDataContextInitializer();
}
public DbContext Create()
{
return new DataContext(ModelCreators, Initializer);
}
}
public interface IModelCreator
{
void OnModelCreating(DbModelBuilder modelBuilder);
}
public class DataContext : DbContext
{
public DataContext(IEnumerable<IModelCreator> modelCreators, IDatabaseInitializer<DataContext> initializer)
{
ModelCreators = modelCreators;
if (initializer != null)
{
Database.SetInitializer(initializer);
}
}
private IEnumerable<IModelCreator> ModelCreators { get; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
foreach (var creator in ModelCreators)
{
creator.OnModelCreating(modelBuilder);
}
}
}
每个插件定义它自己的IModelCreator
。
然后,实体将被`DbContext.Set()。
问题是EF不会创建额外的表,它会丢弃数据库或抛出异常(取决于使用的初始化程序)。当我打开迁移时,我无法生成迁移,因为项目中没有DbContext
所在的模型。
每个插件是否必须提供SQL脚本来创建它的表格,或者EF是否有办法在运行时为使用插件导入的实体添加表格?
如果我实现自己的IDatabaseInitializer
,我怎么能告诉它创建丢失的表?
答案 0 :(得分:1)
我使用了MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration> Class。
我创建了CompositeDataContextInitializer
并更改了我的DataContextFactory
,将其作为参数传递给我的DataContext
。
public class CompositedDataContextInitializer : MigrateDatabaseToLatestVersion<DataContext, Migrations.MigrationConfiguration>
{
protected virtual void Seed(DataContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
foreach (var seeder in ServiceLocator.Current.GetAllInstances<IDataSeeder>())
{
seeder.Seed(context);
}
}
}
[Export(typeof(IDbContextFactory<DbContext>))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class ContextFromCompositionFactory : IDbContextFactory<DbContext>, IDbContextFactory<DataContext>
{
public DbContext Create() => new DataContext(ServiceLocator.Current.GetAllInstances<IModelCreator>(), new CompositedDataContextInitializer());
DataContext IDbContextFactory<DataContext>.Create() => (DataContext)Create();
}
public interface IModelCreator
{
void OnModelCreating(DbModelBuilder modelBuilder);
}
public class DataContext : DbContext
{
public DataContext(IEnumerable<IModelCreator> modelCreators, IDatabaseInitializer<DataContext> initializer)
{
ModelCreators = modelCreators;
if (initializer != null)
{
Database.SetInitializer(initializer);
}
}
private IEnumerable<IModelCreator> ModelCreators { get; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
foreach (var creator in ModelCreators)
{
creator.OnModelCreating(modelBuilder);
}
}
}
TPT Inheritance仍然存在一些问题;如果要存储从系统中已有的类继承的新类,请使用TPH Inheritance。