Могу ли я поместить вызов Database.SetInitializer в конструктор контекста с базовой строкой вместо статического конструктора?

Я использую Entity Framework для хранения некоторых сущностей, созданных во время выполнения с помощью Codedom. На самом деле я также динамически создаю свои контексты, используя Codedom. Прежде чем я начал динамически генерировать контексты, я использовал жестко закодированный контекст. Начало этого жестко запрограммированного класса контекста (до конструкторов) выглядело так:

public class EntityModelContext : DbContext, IEntityRegistry
{
    static EntityModelContext()
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EntityModelContext>());
    }

    public EntityModelContext()
        : base("EntityModelContext")
    {
        EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
    }

Все это было хорошо. Однако я попытался сгенерировать это с помощью Codedom и обнаружил, что статика не имеет значения для Codedom. Даже если бы я мог сгенерировать статический конструктор, я бы получил ошибку, которая в основном говорила о том, что есть два конструктора, и я не знаю, какой из них использовать. Итак, затем я объединил эти два конструктора в своем классе контекста, сгенерированном Codedom, и теперь он выглядит так (обратите внимание, он называется TreeContext, потому что я создаю контекст для каждой сущности, которую я создаю, и я создаю сущность дерева в своих тестах) :

TreeContext() : 
        base("TreeContext")
{
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TreeContext>());
    EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
}

Я только что попытался запустить тест, который генерирует класс сущности дерева и экземпляр этой сущности дерева, а также соответствующий класс контекста дерева и экземпляр этого контекста дерева. Я попытался вставить этот экземпляр объекта дерева в экземпляр контекста дерева, и, похоже, он работал в SQL Server. Поэтому я думаю, что конструктор работает. Однако я хотел убедиться, что кто-то еще лучше понимает, как работает Database.SetInitializer. Я думал, что его нужно вызывать до вызова базовой строки подключения, но, похоже, это работает. Во всяком случае, я только протестировал вставку экземпляра объекта. Я не пробовал менять модель или что-то более сложное.


person Drew    schedule 03.07.2015    source источник


Ответы (1)


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

System.Data.Entity.Database.SetInitializer(...);

Обычно вызывается при первом доступе к функциям контекста (недостаточно для создания контекста). Обычно сначала читают или сначала SaveChanges.

Вы также можете сгенерировать статический конструктор с помощью CodeDom с помощью CodeTypeConstructor вместо CodeContructor.

person bubi    schedule 03.07.2015