Место для размещения Database.SetInitializer - PullRequest
31 голосов
/ 30 декабря 2011

Я работаю над проектом, который может в конечном итоге иметь несколько версий / вариантов пользовательского интерфейса, но до сих пор у меня есть два подпроекта в моем веб-интерфейсе решения, содержащем ASP.NET MVC. Сервисный проект - это место, где у меня есть контекст базы данных и определенные модели.

Моя цель состоит в том, чтобы в моем веб-проекте имелось минимальное количество ссылок на конкретный код EF или, возможно, вообще нет. Я хочу, чтобы он был независимым, поэтому, когда я переключаю dll с сервисным бэкэндом (скажем, с SQL на XML или MySQL), я не должен делать несколько модификаций в своем проекте MVC.

Вот как это выглядит:

Project layout

Мои вопросы: - пока что я не нашел примера использования Database.SetInitializer в другом месте, кроме Global.asax. Я хотел бы добавить пересоздание базы данных, если модель изменилась в моем фабричном классе DatabaseContextProvider или в классе обслуживания, который извлекает данные из контекста и предоставляет их в пользовательский интерфейс с DTO. Есть ли минусы этого места? - Хотелось бы, чтобы контекстная строка подключения была настраиваемой с помощью файла Properties / Settings.settings - это разумно?

Ответы [ 5 ]

36 голосов
/ 16 июня 2013

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

static MyDataContext()
{
   Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDataContext, Configuration>());
}

Строка подключения, конечно, будет взята из файла конфигурации приложения.

14 голосов
/ 30 декабря 2011

Вам понадобится механизм для вызова метода Database.SetInitializer перед самым первым использованием DbContext.Вот почему он обычно вызывается в файле Global.asax.

Вы можете создать класс с методом инициализации в своем проекте tm.Service, вызвать его в методе Application_Start и поместить Database.SetInitializer вэтот метод инициализации.

Можно предоставить строку подключения из файла настроек.

9 голосов
/ 13 апреля 2013

Я положил его на конструктор DbContext и работает для меня.

public myDbContext() : base(connectionToDatabase) {
        Database.SetInitializer<myDbContext>(null);
    }

Решение, приведенное выше, будет работать, но оно не так эффективно, как следующий код:

  protected void Application_Start()
    {
        Database.SetInitializer<myDbContext>(null);
    }

В моем случае у меня нет ссылки на мой DAL в пользовательском интерфейсе, и по этой причине я создал конфигурацию EntityFramework и зарегистрировал свою настройку, используя отражение.

 protected void Application_Start()
    {           
        EntityFrameworkConfig.RegisterSettings();
    }


 public static class EntityFrameworkConfig
{
    public static void RegisterSettings()
    {
        // Use the file name to load the assembly into the current
        // application domain.
        Assembly a = Assembly.Load("MyAssembly");
        // Get the type to use.
        Type myType = a.GetType("MyType");
        // Get the method to call.
        MethodInfo myMethod = myType.GetMethod("MySettingsMethod");
        // Create an instance.
        object obj = Activator.CreateInstance(MyType);
        // Execute the method.
        myMethod.Invoke(obj, null);
    }
}

  public void Configurations()
    {
      //Other settings
        Database.SetInitializer<myDbContext>(null);
    }

Обновлено

В Entity Framework 6 теперь вы можете использовать NullDatabaseInitializer

Database.SetInitializer(new NullDatabaseInitializer<MyDbContext>());
3 голосов
/ 31 октября 2016

Microsoft позволила, начиная с EF6, настраивать один инициализатор для каждого контекста базы данных в файле конфигурации приложения.См. Последний раздел на этой странице Microsoft: https://msdn.microsoft.com/en-us/data/jj556606.aspx

Это, как и подход "Global.asax", имеет то преимущество, что, например, проекты модульного тестирования могут использовать другой инициализатор для того же контекста базы данных.

0 голосов
/ 24 марта 2018

Щелкните страницу Global.asax, и вы найдете метод Application_Start (). Внутри этого метода после этого следующего кода. Для поддержки этого кода используйте пространство имен с помощью System.Data.Entity;

Database.SetInitializer<namespace.modelclass>(null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...