Skip to main content
 首页 » 编程设计

c#之WebSecurity.InitializeDatabaseConnection 不配合代码优先迁移

2024年02月01日27zhoujg

在我的项目中,我使用 WebSecurity 和 EF 代码优先迁移。

我有我的自定义 UserProfile 类,我想将其与 WebSecurity 结合。

我想在 Seed 方法的迁移配置类中为用户播种。

所以我试试这个:

#1) 
if (!Roles.RoleExists("admin")) 
            Roles.CreateRole("admin"); 
 
if (!WebSecurity.UserExists(AdminUserName)) 
    WebSecurity.CreateUserAndAccount( 
        AdminUserName, 
        "admin", 
        new {Email = "admin@mindmap.pl"}); 

但它提示我应该先调用 WebSecurity.InitializeDatabaseConnection。

好的,这是有道理的。所以我将以下行添加到我的 Global.asax 中:

#2) 
WebSecurity.InitializeDatabaseConnection( 
    _connectionStringName, 
    "UserProfiles", 
    "Id", 
    "UserName", 
    autoCreateTables: true); 

但比下面几行:

#3) 
var dbMigrator = new DbMigrator(_configuration); 
dbMigrator.Update(); 

抛出错误:

There is already an object named 'UserProfiles' in the database.

好吧,这再次有意义,因为迁移会尝试创建刚刚由 WebSecurity 创建的表。

我找到了一个解决方法:我将#2) 放在#1) 的正上方。比它奏效。

  1. 迁移创建了 UserProfiles 表
  2. WebSecurity 附加到现有的 UserProfiles 表并创建它需要的其他表
  3. Seeds 在找到所需的表并初始化 WebSecurity 后开始工作。

问题是我必须在 seed 方法中初始化 WebSecurity,这有点臭。

我的问题是如何将 WebSecurity.InitializeDatabaseConnection 移回 Global.asax?

请您参考如下方法:

您可以在 Global.asax 中编写此代码:

if (!WebMatrix.WebData.WebSecurity.Initialized) 
                WebSecurity.InitializeDatabaseConnection(_connectionStringName, "UserProfile", "UserId", "UserName", autoCreateTables: true); 

然后通过这种方式使用迁移进行播种,您可以在此处放置自定义字段,例如电子邮件,...:

private void SeedMemberShip() 
{ 
    if (!WebMatrix.WebData.WebSecurity.Initialized) 
        WebSecurity.InitializeDatabaseConnection(_connectionStringName, "UserProfile", "UserId", "UserName", autoCreateTables: true); 
    var roles = (SimpleRoleProvider)Roles.Provider; 
    var membership = (SimpleMembershipProvider)Membership.Provider; 
    if (!roles.RoleExists("Admin")) 
    { 
        roles.CreateRole("Admin"); 
    } 
 
    if (membership.GetUser(username, false) == null) 
    { 
        membership.CreateUserAndAccount(username, password); 
    } 
 
    if (!roles.GetRolesForUser(username).Contains("Admin")) 
    { 
        roles.AddUsersToRoles(new[] { username }, new[] { "Admin" }); 
    } 
} 

然后调用上面的方法就是seed方法:

protected override void Seed(YourContext context) 
        { 
 
            SeedMemberShip(); 
        }