Как разрешить инициализатор базы данных EF4 CodeFirst запускаться под разработку, но не запускаться в процессе производства
Я пытаюсь развернуть свою первую альфа-версию системы онлайн для нескольких человек, чтобы начать использовать. При разработке я активно использую DropCreateDatabaseOnModelChange<TContext>
(у меня его нет на данный момент, поэтому я не могу проверить точное имя), чтобы повторно инициализировать мою базу данных dev каждый раз, когда меняет модель. Это происходит в Global.asax
.
Однако я не хочу, чтобы это происходило на моем веб-хосте, где другие люди вводят реальные данные. Мне нужно обрабатывать все миграции db там, поэтому данные сохраняются.
Я рассмотрел теги #ifdef DEBUG
, чтобы предотвратить вызывать инициализатор базы данных, но мне не нравится это решение. Прямо сейчас, у меня версия отладки развернута, поэтому, если они сталкиваются с любыми ошибками, мне легко увидеть и отладить их (это очень альфа, поэтому только немногие используют его и знают, что ожидать ошибок).
Какие еще параметры я должен предотвратить, прежде всего, для того, чтобы предотвратить падение кода программы с помощью кода EF4?
Ответы
Ответ 1
Вы всегда можете создать новую конфигурацию (в дополнение к Debug и Release). Затем вы определяете условный символ компиляции для новой конфигурации. Например, если я создал новую конфигурацию под названием LocalDebug (с теми же настройками при отладке по умолчанию), я бы добавил LOCALDEBUG в условные символы компиляции. С помощью этого определения вы можете использовать:
#if LOCALDEBUG
//do database stuff
#endif
Затем вы можете развернуть встроенную конфигурацию отладки, и этот раздел не будет срабатывать.
Ответ 2
Как насчет инверсии управления:
var initializer = container.Resolve<IDatabaseInitializer<Context>>();
Database.SetInitializer(initializer);
На основе вашей конфигурации IoC вы либо вернетесь к разработке или инициализации производства. У вас может быть другой файл конфигурации для каждой конфигурации сборки, поэтому вы также можете настроить контейнер IoC по-разному.
public class ThrowExceptionInitializer : IDatabaseInitializer<Context>
{
public InitializeDatabase(Context context)
{
// Custom exception
throw new InvalidVersionException("The new application version is not supported by the database version");
}
}
Ответ 3
Как говорит @Johann, ConditionalAttribute
, вероятно, является решением для очистки здесь:
[Conditional("DEBUG")]
private void InitializeDb()
{
// Initializer code here
// DropCreateDatabaseOnModelChange<TContext>
}
и в Global.asax:
public void Application_Start // or wherever it is you're initializing
{
// This will only be called if the DEBUG constant is defined
InitializeDb();
}
Ответ 4
Вы можете использовать атрибут Conditional, но он не так сильно отличается от #ifdef
Ответ 5
Если вы используете sql express в разработке, а не в своей производственной коробке, вы можете фильтровать по соединению.
protected void Application_Start(object sender, EventArgs e)
{
using (var db = new MyDb())
{
if (db.Database.Connection.DataSource.IndexOf("sqlexpress", StringComparison.InvariantCultureIgnoreCase) > -1)
{
Database.SetInitializer(new MyDbInitializer());
}
}
}