ef core new dbcontext выполняет OnModelCreating только один раз - PullRequest
0 голосов
/ 06 марта 2020

у нас регулярно меняются данные базы данных (каждые две недели до одного раза в месяц). Обычно необходимо использовать самые последние данные, но в некоторых особых случаях необходимы более старые данные.

Текущая информация о том, какую версию нужно использовать atm, хранится в другой таблице.

База данных выглядит например, версионные имена схем с теми же таблицами под ним.

YYYYMMDD+Revision

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

Я создал службу As pnet core (2.2) с двумя классами DbContext, один для схем stati c, которые получает текущую версию для использования и одну для изменяющихся схем, которая обращается к этим данным.

stati c DbContext работает просто отлично.

Проблема в том, что даже когда я использую изменяющийся контакт с использованием 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 выполняется каждый раз ? Или, может быть, другое решение, как справиться с этими меняющимися схемами?

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Решено этим ответом { ссылка }

Цитата из примера на случай, если он будет удален.

Производный DbContext, который заменяет это ModelCacheKey (и фабрика) с Custom.

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);

        // ...
    }
}

Фабрика, которая создает Контекст с указанным c ключом.

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;
    }
}

И использование контекста, например.

using (var _myContext = new MyDbContext(_schemaNameToUse)
{
}
0 голосов
/ 06 марта 2020

Продолжить с моего комментария. Приведенный ниже дизайн таблицы базы данных позволяет вам или пользователям добавлять столько новых полей к объекту, сколько они захотят. И я думаю, что это дает наиболее гибкую структуру.

Давайте предположим, что в системе электронной коммерции мы предоставляем 3 поля (Имя, Код, Цена) для продукта. Но мы также разрешаем пользователям добавлять свои собственные поля в свои продукты (например, Promotion1Price, Promotion2Price, Discount, ...)

PRODUCT (ProductId, Name, Code, Price)

CUSTOMEFIELD ( FieldId, FieldName, FieldType)

PRODUCT_CUSTOMFIELD (ProductId, FieldId, FieldValue)

Дайте мне знать, если это не соответствует вашим целям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...