C# 当应用程序启动并创建DbContext时,向DbContext添加新的DbSet

C# 当应用程序启动并创建DbContext时,向DbContext添加新的DbSet,c#,entity-framework,dynamic,C#,Entity Framework,Dynamic,我有一个项目,在商业上它将创建表dynamicali,它与netcore3.0和EF一起工作。 在创建动态表之后创建dbcontext的实例时,我将使用Assembly Emit创建一个新类型的表,并使用OnModelCreating方法添加对应于表的数据库集 public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<Application

我有一个项目,在商业上它将创建表dynamicali,它与netcore3.0和EF一起工作。 在创建动态表之后创建dbcontext的实例时,我将使用Assembly Emit创建一个新类型的表,并使用OnModelCreating方法添加对应于表的数据库集

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Book> Books { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        //Use assmbly emit to create dynamic types
        var types = CreateDynamicTypes();

        foreach (var type in types)
        {
            builder.Entity(type);
        }

        base.OnModelCreating(builder);
    }
}
public类ApplicationDbContext:IdentityDbContext
{
公共应用程序DBContext(DbContextOptions选项)
:基本(选项)
{
}
公共虚拟数据库集书籍{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder)
{
//使用assmbly emit创建动态类型
var types=CreateDynamicTypes();
foreach(类型中的变量类型)
{
建筑商。实体(类型);
}
基于模型创建(生成器);
}
}
但是,当在创建dbcontext之后创建表时,我还不知道如何添加新的dbset,因为OnModelCreating只运行1次


问题是:如何在创建dbcontext实例后向其添加新的DBSet?

由于性能开销,在ModelCreating上仅运行1次(当它首次初始化时)

有一种方法可以绕过这个问题,即使用“模型定制器”

首先,您需要在onconfigurang中进行一些调整(您需要覆盖基本实现)

protectedoverride void onconfiguration(DbContextOptionsBuilder optionsBuilder)
{
基本配置(选项生成器);
var servicecolection=新servicecolection()
.AddEntityFrameworkSqlServer();
serviceCollection=serviceCollection.AddSingleton();
var serviceProvider=servicecolection.BuildServiceProvider();
选项生成器
.UseInternalServiceProvider(服务提供商);
}
你的定制者应该是这样的

public class YourModelCustomizer : ModelCustomizer
    {
        public override void Customize(ModelBuilder modelBuilder, DbContext dbContext)
        {
            base.Customize(modelBuilder, dbContext);

            var entityTypeBuilderCart = modelBuilder.Entity<Models.Cart>()
                .ToTable("ABC");
            entityTypeBuilderCart.Property(a => a.UserId).HasColumnName("XYZ");
            entityTypeBuilderCart.Property(a => a.ContractorId).HasColumnName("DFG");
            entityTypeBuilderCart.Ignore(a => a.CompanyId);

            var entityTypeBuilderCartArticle = modelBuilder.Entity<Models.CartArticle>()
                .ToTable("IJK");
            entityTypeBuilderCartArticle.Property(a => a.UserId).HasColumnName("QWE");
        }

        public YourModelCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies)
        {
        }
    }
公共类YourModelCustomizer:ModelCustomizer
{
公共覆盖无效自定义(ModelBuilder ModelBuilder、DbContext DbContext)
{
自定义(modelBuilder、dbContext);
var entityTypeBuilderCart=modelBuilder.Entity()
.ToTable(“ABC”);
entityTypeBuilderCart.Property(a=>a.UserId).HasColumnName(“XYZ”);
entityTypeBuilderCart.Property(a=>a.ContractorId).HasColumnName(“DFG”);
entityTypeBuilderCart.Ignore(a=>a.CompanyId);
var entityTypeBuilderCartArticle=modelBuilder.Entity()
.ToTable(“IJK”);
entityTypeBuilderCartArticle.Property(a=>a.UserId).HasColumnName(“QWE”);
}
公共YourModelCustomizer(ModelCustomizerDependencies依赖项):基础(依赖项)
{
}
}
我希望它能帮助你

请注意,这种配置可能会导致性能问题。
此代码适用于EF Core 2.x,在EF 3.x中可能会有一些更改,并且此代码可能需要一些更改。

感谢您的快速回复。如果Customize(ModelBuilder,DbContext)调用每个请求,我将尝试了解性能如何?如果有时间,我可以尝试做一些基准测试。在您的应用程序中,最好将使用ModelCustomizer的DbContext与不使用ModelCustomizer的DbContext分开,因为调用ModelCustomizer时,EF无法充分利用缓存,不建议应用程序使用这种方法,最好重新考虑应用程序和使用过程,而不是每次都更改模型。仅调用一次ModelCreating是创建此框架的人员的“设计目标”。
public class YourModelCustomizer : ModelCustomizer
    {
        public override void Customize(ModelBuilder modelBuilder, DbContext dbContext)
        {
            base.Customize(modelBuilder, dbContext);

            var entityTypeBuilderCart = modelBuilder.Entity<Models.Cart>()
                .ToTable("ABC");
            entityTypeBuilderCart.Property(a => a.UserId).HasColumnName("XYZ");
            entityTypeBuilderCart.Property(a => a.ContractorId).HasColumnName("DFG");
            entityTypeBuilderCart.Ignore(a => a.CompanyId);

            var entityTypeBuilderCartArticle = modelBuilder.Entity<Models.CartArticle>()
                .ToTable("IJK");
            entityTypeBuilderCartArticle.Property(a => a.UserId).HasColumnName("QWE");
        }

        public YourModelCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies)
        {
        }
    }