EF5和简单成员资格的数据库初始化问题

时间:2013-01-24 20:29:35

标签: c# .net asp.net-mvc-4 entity-framework-5 simplemembership

我的global.asax文件中有两个数据库初始化程序。

一个应该用相关表创建我的数据库,第二个用于初始化简单成员所需的所有表。

我遇到的问题是应该创建我的数据库的第一个初始化方法没有做任何事情(至少看起来是这样)。简单的会员资格初始化工作正常。

只有在我的存储库类中创建新的上下文实例时,才会创建我想要从我的上下文创建的表。这会失败,因为它正在尝试创建一个已经存在的用户配置文件表,因为WebSecurity.InitialiseDatabaseConnection初始化程序已经创建了它?

为什么在存储库方法中创建上下文之前没有执行第一个数据库初始化程序的原因?

数据库是SQL Server LocalDB。

以下是Application_Start中的Global.asax.cs方法:

protected void Application_Start()
{
    Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
    WebSecurity.InitializeDatabaseConnection("MyDb", "UserProfile", "UserId", "UserName", autoCreateTables: true);

    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new RazorViewEngine());
}

这是Context类:

public class MyContext : DbContext
{
    public MyContext()
        : base("name=MyDb")
    {


    }

    public DbSet<MyEntity> myEntity{ get; set; }
    public DbSet<UserProfile> UserProfiles { get; set; }

}

这是存储库方法:

using (var db = new MyContext())
{

    var user = _userRepository.GetUserByUserName(userName);

    db.UserProfiles.Attach(user);

    if (rack.Id == 0)
    {
        rack.DateAdded = DateTime.Now;
        rack.AddedBy = user;

        db.MyEntity.Attach(rack);
        db.Entry(rack).State = EntityState.Added;
        db.SaveChanges();
    }
    else
    {
        db.MyEntity.Attach(rack);
        db.Entry(rack).State = EntityState.Modified;
        db.SaveChanges();
    }
}

编辑:我已将SimpleMembership初始化程序移动到我的Configuration类的种子方法,如下所示,虽然这解决了以正确的顺序创建表的问题但我仍然没有关于在Application_Start方法中调用初始化程序时数据库未初始化的原因的明智之处

protected override void Seed(RackTrackContext context)
    {
        WebSecurity.InitializeDatabaseConnection("MyDb", "UserProfile", "UserId", "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("User1"))
            WebSecurity.CreateUserAndAccount(
                "User1",
                "CodeMonkey"
                );

        if (!Roles.GetRolesForUser("User1").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] { "User1" }, new[] { "Administrator" });
    }

编辑No2:

为了使它工作,我使用了在Application_start方法中创建了一个新的上下文,并从db中检索了一个结果。然后,这将在我希望应用它们的阶段应用迁移。

它很乱,很丑,不会赢得任何奖项,但嘿它有效,没有动物在做的时候受到伤害,所以就这样了。

 protected void Application_Start()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());

        //this code is here to ensure that the context is created and migrations applied,
        //prior to the user seeing the start screen for the app. Must be a better way of doing it....
        using (var db = new MyContext())
        {
            var results = db.MyEntity.FirstOrDefault();
        }

如果有人能告诉我一个更好的方法,那就有一些代表可以争夺!

1 个答案:

答案 0 :(得分:0)

而不是

    using (var db = new MyContext())
    {
        var results = db.MyEntity.FirstOrDefault();
    }

new MyContext().Database.Initialize(false)
if (!WebSecurity.Initialized)
    WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);