40

我遇到了新的 ASP MVC 4 特性,它附带了新的成员数据库模式和新的初始化。在 mvc 3 和旧版本中,开发人员能够使用 web.config 中的规范创建自定义用户配置文件字段,但现在我遇到了默认 mvc 4 项目中过滤器命名空间中的方法:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

和用户资料表:

[Table("UserProfile")]
    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
    }

但是 InitializeDatabaseConnection 方法只生成 UserName 和 UserId 我需要生成其他附加字段。

我在 EF codeFirst 方法方面有很好的经验,在这种情况下,我尝试编辑 UserProfile 类:

[Table("UserProfile")]
    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        [Column]
        [Required]
        public string UserName { get; set; }
        [Column]
        [Required]
        public string FirstName { get; set; }
        [Column]
        [Required]
        public string LastName { get; set; }
    }

但是当我重新生成数据库时,我没有看到任何更改,没有生成自定义数据库字段。请帮助我,如何创建自定义用户字段?

4

5 回答 5

52

从上面的答案详细说明

方法WebSecurity.InitializeDatabaseConnection帮助指出

如果要使用包含用户配置文件信息(用户名、电子邮件地址等)的数据库表,则指定成员资格系统用于连接到该信息的连接字符串和表名。如果您不想使用现有的用户配置文件表,您可以指定 InitializeDatabaseConnection() 方法应该自动创建用户配置文件表。(用户配置文件表的数据库必须已经存在。)

因此,如果我们想在UserProfile表中添加更多字段,我们只需要确保我们正在创建一个配置文件表并InitializeDatabaseConnection在表已经就位后运行该方法。

在 VS2012 的标准 MVC4.0 项目模板中,我注释掉了 Account 控制器

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
{

并移至InitializeDatabaseConnectionEF Code First Database Initializer

public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext>
{
    protected override void Seed(MyDatabaseContext context)
    {
        SeedMembership();
    }

    private void SeedMembership()
    {
        WebSecurity.InitializeDatabaseConnection("MyDatabaseContext",
            "UserProfile", "UserId", "UserName", autoCreateTables: true);
    } 
}

确保InitializeDatabaseConnection一旦桌子已经就位就运行。

将该UserProfile类添加到我的 EF Code First 模型中

public class MyDatabaseContext : DbContext
{
    public DbSet<UserProfile> UserProfiles { get; set; }

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

UserProfile在表格中添加了额外的字段

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string MobilePhone { get; set; }
}

您现在需要做的就是在应用程序启动时设置数据库初始化策略,并在数据库上调用一个查询,以确保在调用任何授权/身份验证代码之前创建它。

protected void Application_Start()
{
   AreaRegistration.RegisterAllAreas();

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

   Database.SetInitializer<MyDatabaseContext>(new MyDatabaseInit());
   new MyDatabaseContext().UserProfile.Find(1);
}
于 2012-09-17T14:28:05.113 回答
18

基于 IMLiviu 的回答和评论的非破坏性版本:

刚刚遇到这个问题,不得不从答案+评论(+反复试验)中解开正确的方法,所以我想我会分享你可以剪切和粘贴的结果。这是基于 IMLiviu 的回答,所以完全归功于他们。它会修改现有的UserProfileUserContext类,因为它们看起来与 EF 直接兼容:

我很震惊地看到一个涉及完全删除数据库的建议,只是添加几个表,所以在阅读所有评论并创建原型之后,结果如下。

1 - 停止 Webmatrix 创建

停止成员表的标准 webmatrix 创建(注释掉 [InitializeSimpleMembership] 属性)。

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller

2 - 创建迁移配置

创建一个迁移配置类,如下所示:

public class MigrationConfiguration : DbMigrationsConfiguration<UsersContext> 
{
    public MigrationConfiguration()
    {
        this.AutomaticMigrationsEnabled = true;  // This is important as it will fail in some environments (like Azure) by default
    }

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

3 - 从 EF 创建中删除多元化

更改 AccountModel.cs 文件UsersContext类以删除复数选项(添加 OnModelCreating 事件):

public class UsersContext : DbContext
{
    public UsersContext() : base("DefaultConnection")
    {
    }

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

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

4 - 向 UserProfile 添加新字段

将您需要的额外字段添加到 UserProfile:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string UserEmail { get; set; }  // <<<<<<<< E.G. THIS ADDED
}

5 - 在应用启动时迁移表

现在,当应用程序启动时,您设置数据库初始化策略并通过读取触发它:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

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

        Database.SetInitializer(new MigrateDatabaseToLatestVersion<UsersContext, MigrationConfiguration>());
        new UsersContext().UserProfiles.Find(1);
    }

显然,您将需要添加各种 using 语句才能使这一切正常工作,但右键单击解决选项将为您做到这一点。

补充笔记:

如果您决定(像我一样)使用除用户以外的表格UserProfile,则需要更改几个条目以匹配。

  • 在您的SimpleMembershipInitializer班级中,您需要引用新的表名和列名
  • 在帐户控制器和各种登录和注册视图中,您需要引用您的新模型字段(如果名称已更改)
  • UsersContext类中,您可以保留 Userprofile 类名,但您需要更改Table属性以匹配您的表名。
  • UserProfile类中,您需要重命名字段以匹配您的新表字段名称。
  • 在数据库中,您需要删除和之间的关系,webpages_UsersInRolesUserProfile在新用户表和webpages_UsersInRoles/或旧的引用完整性检查之间添加关系,这将在运行时破坏您。(我强烈建议您删除现有UserProfile表并检查它是否没有重新创建。如果是您的代码中留下了一些东西)。
于 2013-10-09T15:21:00.030 回答
6

将新表添加到数据库并将其命名为 User_Details 或类似名称,在创建用户时,您可以检索用户的 ID 并将详细信息强制到新表中。这是一个简单的选择。

于 2013-01-07T16:27:45.537 回答
3

查看 VS2012 或 VS2010 附带的 MVC4 互联网项目模板。在修改 userprofile 类的列之前,您需要确保未创建数据库。您可以在 POCO 类中添加更多属性,然后重新生成数据库。如果您在生成数据库后添加属性,请确保您正在使用 EF 迁移将这些新属性添加到数据库

于 2012-09-16T20:35:57.640 回答
3

当然,您可能知道您必须使您RegisterModelUserProfile Model. 我喜欢做的是在初始化数据库之前使用迁移并将以下内容放入Configuration.cs文件中:

    protected override void Seed(UsersContext context)
    {

        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!WebSecurity.UserExists("yardpenalty"))
            WebSecurity.CreateUserAndAccount(
                "yardpenalty",
                "password",
                new
                {
                    Email = "youremail@yahoo.com",
                    ImageUrl = "/Content/Avatars/yourname",
                    DateJoined = DateTime.Now
                },
                false);  
           //... rest of model.Builder stuff 
   }

然后我使用Packet Manager Console这三个容易记住的命令:

  1. 启用迁移
  2. 添加迁移迁移名称
  3. Update-Database // 将从 Configuration.cs 播种

我同意TrueBlueAussie,并且会说 LazyInitialization 不再很有帮助,你真的不必再像以前那样称呼它了。无论如何,您所要做的就是在您的帐户控制器中更改注册操作以调用方法,如下所示:

  WebSecurity.CreateUserAndAccount(model.UserName, model.Password, propertyValues: new { model.Email, model.ImageUrl, model.DateJoined });

注意:MVC5 使用 OWIN

于 2013-12-14T19:46:01.453 回答