EF Code первая инициализация базы данных / таблицы - КОГДА это происходит? - PullRequest
0 голосов
/ 13 октября 2011

Мое приложение использует EF-дизайн, и все в целом работает очень хорошо.

Через личный файл конфигурации я могу указать, как я хотел бы, чтобы EF обрабатывал изменения в схеме БД, и, таким образом, создавал / создавал соответствующие таблицы по желанию - параметры «никогда», «создавать», «всегда», "onSchemaChanged" и (на будущее) "onSchemaModified".

Это хорошо работает - но я теряюсь в нескольких местах .....

Во время разработки я хотел бы использовать хук, как описано в « Ошибка использования базы данных с Entity Framework 4 Code First » - но, похоже, это выполняется при КАЖДОМ запуске программы »

 public void InitializeDatabase(Context context)
    {
        context.Database.SqlCommand("ALTER DATABASE Tocrates SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
        _initializer.InitializeDatabase(context); // Maybe this does nothing if not needed
        context.Database.SqlCommand("ALTER DATABASE Tocrates SET MULTI_USER")
    }

Итак ... чтобы ответить на мой вопрос: есть ли переопределение, которое я могу использовать, чтобы определить, будет ли EF НАСТОЯЩЕМУ пытаться изменить базу данных, чтобы я мог установить этот материал SINGLE_USER при необходимости? И если да, могу ли я обнаружить причину EF, которую он делает (см. Мой список вариантов выше), чтобы я мог записать причину изменения? ...

Вся помощь и предложения очень ценятся.

1 Ответ

2 голосов
/ 13 октября 2011

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

  • Для DropCreateDatabaseAlways и CreateDatabaseIfNotExists по их названию ясно, что они делают.

  • Для DropCreateDatabaseIfModelChanges возникает только вопрос, изменилась модель или нет. EF обнаруживает это, сравнивая хеш модели с хешем, хранящимся в базе данных. Вы можете сами проверить это, позвонив ...

    bool compatible = context.Database.CompatibleWithModel(true);
    

    ... в пределах вашего пользовательского InitializeDatabase и затем на основе результата решите, хотите ли вы отправлять SqlCommands или нет. (Не называйте это с помощью самостоятельно созданного context, потому что это приведет к инициализации базы данных first до проверки совместимости модели.) Параметр bool throwIfNoMetadata (который true in мой пример) заставляет EF генерировать исключение, если хеш модели в базе данных не существует. В противном случае метод вернет true в этом случае.

  • Для пользовательского внутреннего инициализатора: что бы ни делал ваш код.

...