繁体   English   中英

ef core new dbcontext 只执行一次 OnModelCreating

[英]ef core new dbcontext executes OnModelCreating only once

我们定期更改数据库数据(每两周到每月一次)。 通常必须使用最新的数据,但在某些特殊情况下,需要使用较旧的数据。

必须使用 atm 版本的当前信息存储在另一个表中。

数据库看起来像这样,版本化的 Schema-Names 在它下面有相同的表。

YYYYMMDD+Revision

myshema_202001011
    table1
myshema_202002011 and so on
    table1
myshema_202003011 and so on
    table1

我已经使用两个 DbContext 类构建了一个 Aspnet 核心 (2.2) 服务,一个用于获取当前版本使用的静态模式,另一个用于访问这些数据的更改模式。

静态 DbContext 工作得很好。

问题是,即使我使用不断变化的 contaxt 和 using like,

using (var _context = new ChangingDbContext()){}

构造函数和OnConfiguring都执行,但OnModelCreating方法只执行一次 这导致更新到当前模式。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");

    modelBuilder.Entity<my_table>(entity =>
    {
        entity.HasKey(e => e.key_adr);
        entity.ToTable("mytable", $"myshema{mySchemaVersion}");
    }); 
}

有没有人知道如何获得每次都执行OnModelCreating的“真正”新上下文? 或者也许是另一种解决方案如何处理那些不断变化的架构?

继续我的评论。 下面的 db 表设计允许您或用户根据需要向对象添加任意数量的新字段。 我认为它提供了最灵活的结构。

假设在电子商务系统中,我们为产品提供 3 个字段(名称、代码、价格)。 但我们也允许用户将他们的自定义字段添加到他们的产品中(例如 Promotion1Price、Promotion2Price、Discount 等)

产品(产品 ID、名称、代码、价格)

自定义字段(字段 ID、字段名称、字段类型)

PRODUCT_CUSTOMFIELD (ProductId, FieldId, FieldValue)

如果这不符合您的目的,请告诉我。

由这个答案解决https://stackoverflow.com/a/41985226/6692289

引用 Example 以防它被删除。

派生的 DbContext 用自定义的替换它的 ModelCacheKey(和工厂)。

 class MyDbContext : DbContext { public MyDbContext(string schema) { Schema = schema; } public string Schema { get; } protected override void OnConfiguring(DbContextOptionsBuilder options) => options .UseSqlServer("...") .ReplaceService<IModelCacheKeyFactory, MyModelCacheKeyFactory>(); protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasDefaultSchema(Schema); // ... } }

使用特定键创建上下文的工厂。

 class MyModelCacheKeyFactory : IModelCacheKeyFactory { public object Create(DbContext context) => new MyModelCacheKey(context); }

每个上下文的自定义 ModelCacheKey。

 class MyModelCacheKey : ModelCacheKey { string _schema; public MyModelCacheKey(DbContext context) : base(context) { _schema = (context as MyDbContext)?.Schema; } protected override bool Equals(ModelCacheKey other) => base.Equals(other) && (other as MyModelCacheKey)?._schema == _schema; public override int GetHashCode() { var hashCode = base.GetHashCode() * 397; if (_schema != null) { hashCode ^= _schema.GetHashCode(); } return hashCode; } }

并使用 Context 之类的。

using (var _myContext = new MyDbContext(_schemaNameToUse)
{
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM