ASP.NET MVC 3 дочерний запрос запускается до того, как Entity Framework DatabaseInitializer завершит создание таблиц и заполнение базы данных? - PullRequest
3 голосов
/ 15 июня 2011

У меня есть приложение ASP.NET mvc3, которое использует ninject для DI. Приложение использует Entity Framework 4 и инициализатор базы данных, который также загружает пользовательские данные в базу данных.

Инициализатор базы данных работает в HttpApplication.Application_Start.

Однако я получаю сообщение об ошибке, потому что кажется, что дочерний запрос вызывается до того, как инициализатор базы данных завершил создание и заполнение базы данных :

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

Мой _layout.cshtml имеет дочерний запрос:

@Html.Action("Present", "Time")

Что это:

[ChildActionOnly]
public ActionResult Present()
{
    //HttpContext.Trace.Write("Inside [ChildActionOnly]\npublic ActionResult Present() (child requests that is called by _layout.cshtml)");
    System.Diagnostics.Debugger.Launch();
    Employee employee = this.employeeService.CurrentEmployee;

Однако, как только база данных будет успешно создана и заполнена моим инициализатором базы данных под названием «EFZeiterfassungDataContextInitializer» (он наследует от DropCreateDatabaseIfModelChanges), приложение работает.

У меня проблема только с первым (дочерним) запросом!

В моём вспомогательном модуле я сконфигурировал мой текст данных (называемый EFZeiterfassungContext) следующим образом:

Bind<EFZeiterfassungContext>().ToSelf().InRequestScope();

Дополнительная информация:

Вот код моего приложения Http:

public void SetupDependencyInjection()
{
    // Create Ninject DI Kernel 
    IKernel kernel = new StandardKernel(new ZeiterfassungNinjectModule());
    //Tell asp.net mvc  to use our ninject di container
    DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}

protected void Application_Start()
{
    SetupDependencyInjection();
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    InitializeDatabase();
}

private void InitializeDatabase()
{
    IActiveDirectoryService adService = DependencyResolver.Current.GetService<IActiveDirectoryService>();
    IEmployeeService employeeService = DependencyResolver.Current.GetService<IEmployeeService>();
    EFZeiterfassungDataContextInitializer d = new EFZeiterfassungDataContextInitializer(
        Server.MapPath("~/Content/UserImages/"),
        adService,
        employeeService);
    Database.SetInitializer<EFZeiterfassungContext>(d);
}

РЕДАКТИРОВАТЬ + обходной путь:

Очевидно, Database.SetInitializer(d); возвращается немедленно. инициализатор запускается не сразу - даже асинхронно. EF сначала проверяет БД на наличие изменений, если у вас есть какое-то взаимодействие с текстом данных, т. Е. Путем запроса некоторого значения из еще не существующей БД. Я мог бы обойти это, позвонив var currentEm = employeeService.GetById(1); после Database.SetInitializer(d);. таким образом, БД действительно инициализируется в application_start, а не позже.

Я хотел бы увидеть перегруженный метод SetInitializer, чтобы вы могли немедленно запустить этот процесс.

Я все еще заинтересован в лучшем решении для этого, пока у SetInitializer не появится такой перегруженный метод.

...