应用程序启动时种子数据库 - ASP MVC 3和EF

4

由于某些原因,我无法让我的应用程序在启动时使用一些测试数据填充数据库。

执行顺序:

     1) Application_Start() in Global.asax

         - Database.SetInitializer<LocatorContext>(new DropCreateDatabaseAlways<LocatorContext>());

         - new LocatorContext.DropCreateIfChangeInitializer()
           .InitializeDatabase(new LocatorContext());

     2) onModelCreating() in my DBContext class 


     3) Page is rendered and no data is inserted into the database

任何关于为什么或如何修复的想法都将不胜感激。 我的Global.asax.cs文件
//Global.asax.cs
protected void Application_Start()
{
    Database.SetInitializer<LocatorContext>(new DropCreateDatabaseAlways<LocatorContext>());

    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

我的DBContext类

//ClubLocatorContext.cs        
using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using ClubLocator.Models;
using ClubLocator.Models.ViewModels;

namespace ClubLocator.DAL
{
    public class LocatorContext : DbContext
    {

      public DbSet<Prospect> Prospects { get; set; }

      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          base.OnModelCreating(modelBuilder);
          modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
      }

      public void Seed(LocatorContext context)
      {
          var prospect = new List<Prospect>
                         {
                              new Prospect
                              {
                                      FirstName = "John",
                                      LastName = "Smith",
                                      Address1 = "1313 Mockingbird Lane",
                                      Email = "jsmith@example.com"
                              }
                         };

          prospect.ForEach(r => context.Prospects.Add(r));
          context.SaveChanges();
      }

      public class DropCreateIfChangeInitializer : DropCreateDatabaseIfModelChanges<LocatorContext>
      {
          protected override void Seed(LocatorContext context)
          {
              context.Seed(context);
              base.Seed(context);
          }
      }

      public class CreateInitializer : DropCreateDatabaseAlways<LocatorContext>
      {
          protected override void Seed(LocatorContext context)
          {
              context.Seed(context);
              base.Seed(context);
          }
      }

      static LocatorContext()
      { 
          #if DEBUG
          Database.SetInitializer<LocatorContext> (new DropCreateIfChangeInitializer ());
          #else
          Database.SetInitializer<LocatorContext> (new CreateInitializer ());
          #endif
      }
    }
}
1个回答

10

首先,你的EF代码看起来很好。

问题在于,你需要初始化你的数据库。否则,EF将会等待直到你某种方式访问它才进行初始化。

如果没有页面访问数据,你可以随意浏览网站而不启动数据库。

如果你想要在应用程序启动时强制初始化数据库,请像这样做:

using (var db = new LocatorContext())
{
    db.Database.Initialize(true);
}

我通常会创建一个静态类,例如:

public static class LocatorInitializationHandler
{
    public static void Initialize()
    {
        // if you want to use your initializer
        Database.SetInitializer(new CreateInitializer()); 

        using (var db = new LocatorContext())
        {
            db.Database.Initialize(true);
        }
    }
}

然后我可以从App_start调用它:

//Global.asax.cs
protected void Application_Start()
{
    LocatorInitializationHandler.Initialize();

    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

@Yoda 这是基于可工作的代码和OPs帖子,如果你只是复制/粘贴这段代码,你没有CreateInitializer类,它显然不会起作用。另一个问题是,如果您正在使用EF 6并使用初始化器进行迁移,这将导致错误。 - Jim Wolff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接