模块化系统中的EF核心

时间:2017-05-15 05:26:54

标签: c# entity-framework asp.net-core .net-core entity-framework-core

我开始用asp.net核心开发模块化系统。 系统有模块加载器,模块安装程序等。 每个模块都有自己的数据库模型,动态添加到Context

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
      var typeToRegisters = new List<Type>();
      foreach (var module in GlobalConfiguration.Modules)
      {
          typeToRegisters.AddRange(module.Assembly.DefinedTypes.Select(t => t.AsType()));
      }

      RegisterEntities(modelBuilder, typeToRegisters);
      base.OnModelCreating(modelBuilder);
}

private static void RegisterEntities(ModelBuilder modelBuilder, IEnumerable<Type> typeToRegisters)
{
      var entityTypes = typeToRegisters.Where(x => x.GetTypeInfo().IsSubclassOf(typeof(IEntity<>)) && !x.GetTypeInfo().IsAbstract);
      foreach (var type in entityTypes)
      {
          modelBuilder.Entity(type);
      }
}

但是如果没有迁移,EF Core就无法运行。 我可以为所有模块创建所有迁移文件并在start中运行它,但这是错误的。也许一个模块根本不需要安装。

有没有办法让每个模块都有自己的迁移? 或以任何方式解决这个问题?

抱歉我的英文不好

由于

1 个答案:

答案 0 :(得分:6)

  

但是如果没有迁移,EF Core就无法运行。

有效! EF Core与EF 6.x不同,它没有自动迁移概念。因此,除非您要求使用context.Database.Migrate()方法应用挂起的迁移,否则它根本不会检查迁移历史记录表。因此EF Core不需要显式迁移。要测试它,只需运行您的应用程序,然后您将看到它会抱怨缺少与您实际执行的查询相关的表和字段。它根本不会抱怨失踪的迁移历史。在这种情况下,您可以单独创建数据库表,而无需使用迁移,它可以正常工作。 因此,要独立地进行迁移(这是您的问题),请创建一个类似

的界面
public interface  IModuleDatabaseScript
{
   string CreateSqlSchema { get;}
}

然后你的模块应该实现这个接口并提供create database / create table / alter table / drop table等。 然后您的上下文应该读取这些脚本,然后使用context.Database.ExecuteSqlCommand方法运行它们。您应该在将模块加载到内存一次时执行此操作。在这种情况下,每个模块都可以有或没有(只返回空的CreateSqlSchema字符串)数据库创建策略,而不使用EF Core的迁移机制。