Как принудительно запустить OnModelCreating каждый инициализированный DataContext

Я хочу запускать OnModelCreating каждый new DataContext(new Entity())... Но когда я создаю соединение с таблицей, это работает. При создании соединения для другой таблицы OnModelCreating снова не работает, поэтому, поскольку я получил ошибку,

the entity type <tableName> is not part of the model for the current context.

public class DataContext : DbContext
{
    private BaseEntity _entity;

    public DataContext(BaseEntity entity)
    {
        Database.Connection.ConnectionString = Parameters.ConnectionString;

        _entity = entity;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        _entity.Map(modelBuilder); // this is dynamic fluent api here
    }
}

person canmustu    schedule 04.09.2017    source источник
comment
Вы, кажется, думаете, что контекст может обслуживать только одну сущность за раз. Это неправда, совсем нет. Это очень необычно, что ты здесь делаешь.   -  person Gert Arnold    schedule 20.06.2018


Ответы (2)


ta.speot.is прав в том, что OnModelCreating срабатывает только один раз, потому что modelBuilder кэшируется. Есть несколько случаев, когда требуется повторное выполнение OnModelCreating. Например, когда в сеансах реализована мультиарендность, может потребоваться повторный запуск OnModelCreating.

Когда modelBuilder создается в первый раз, EF кэширует его для повышения производительности. он кэшируется с помощью IDbModelCacheKeyProvider.CacheKey. OnModelCreating срабатывает, когда не находит кэш, связанный с CacheKey. Поэтому, чтобы снова запустить OnModelCreating, необходимо изменить IDbModelCacheKeyProvider.CacheKey.

Чтобы изменить ключ кэша, класс DbContext должен реализовать IDbModelCacheKeyProvider. Когда возвращается новый ключ кэша, в свойстве CacheKey IDbModelCacheKeyProvider событие OnModelCreating запускается снова.

Например, см. следующий блок кода:

public class TenantContext : DbContext, IDbModelCacheKeyProvider
{
    string IDbModelCacheKeyProvider.CacheKey {
        get { return tenentID.ToString(); }
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

Когда tenantID изменяется, OnModelCreating принудительно выполняется, поскольку кэш может быть недоступен для нового tenantID.

Примечание. CacheKey следует менять только в случае крайней необходимости. Частая смена CacheKey снижает производительность.

person Manpreet Singh Dhillon    schedule 20.06.2018
comment
Но они совершенно не должны идти по этому пути. Весь вопрос основан на заблуждении. - person Gert Arnold; 20.06.2018

Руководство поможет вам!

DbContext.OnModelCreating Метод (ДбМоделбуилдер)

...

Примечания

Обычно этот метод вызывается только один раз при создании первого экземпляра производного контекста. Затем модель для этого контекста кэшируется и используется для всех последующих экземпляров контекста в домене приложения. Это кэширование можно отключить, задав свойство ModelCaching для данного ModelBuidler [так в оригинале], но учтите, что это может серьезно снизить производительность. Дополнительный контроль над кэшированием обеспечивается за счет непосредственного использования классов DbModelBuilder и DbContextFactory.

Хотя, если это возможно, вы можете изучить общий DbContext, такой как public class DataContext<TBaseEntity> : DbContext. Это приведет вас к архитектуре, в которой у вас есть один тип DataContext на тип TBaseEntity.

person ta.speot.is    schedule 04.09.2017
comment
Я не могу использовать универсальный, непригодный для моего проекта. Unit Of Work блокирует его в моем проекте. Это использование более полезно для меня на данный момент. - person canmustu; 04.09.2017
comment
Я уже создаю DataContext для каждой сущности, когда есть операция для db. Но после первого создания контекста данных onmodelconfiguring больше не работает. Но мне нужно изменить свободный API, поэтому я должен запустить создание модели. - person canmustu; 04.09.2017
comment
Есть ли способ запустить свободный API для DbModelBuilder во время выполнения? - person canmustu; 04.09.2017
comment
Но после первого создания контекста данных onmodelconfiguring больше не работает Да, так что... этот метод вызывается только один раз... затем модель для этого контекста кэшируется... кэширование можно отключить с помощью установка свойства ModelCaching для данного ModelBuidler [так в оригинале] - person ta.speot.is; 04.09.2017
comment
А если это не сработает... Дополнительный контроль над кэшированием обеспечивается за счет непосредственного использования классов DbModelBuilder и DbContextFactory. - person ta.speot.is; 04.09.2017
comment
я на нем отключаю кеширование - person canmustu; 04.09.2017
comment
Есть ли простой способ отключить кэширование или мне нужно создать собственный DbModelBuilder? - person canmustu; 04.09.2017
comment
Это может быть то, что вам нужно stackoverflow.com/q/29708128/242520 - person ta.speot.is; 04.09.2017
comment
Хорошо, это создает новый DbModelBuilder. Я предполагаю, что отключение кода кеша не так просто. - person canmustu; 04.09.2017