Entity Framework:根据在 MEF 中找到的插件动态更改模型
Entity Framework: dynamically change model based on plugins found with MEF
我正在开发一个应用程序,该应用程序可以使用 MEF 通过插件进行扩展。该应用程序正在使用 Entity Framework。上下文是通过工厂方法创建的:
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
我如何告诉它创建缺失的表?
我用过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; if you want to store new classes which inherit from classes already in system, use TPH Inheritance还有一些问题。
我正在开发一个应用程序,该应用程序可以使用 MEF 通过插件进行扩展。该应用程序正在使用 Entity Framework。上下文是通过工厂方法创建的:
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
我如何告诉它创建缺失的表?
我用过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; if you want to store new classes which inherit from classes already in system, use TPH Inheritance还有一些问题。