如何在MVC4中的UserProfile中创建自定义附加字段

tes*_*der 40 c# asp.net-mvc entity-framework asp.net-mvc-4 simplemembership

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

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Run Code Online (Sandbox Code Playgroud)

和用户档案表:

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

但是方法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; }
    }
Run Code Online (Sandbox Code Playgroud)

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

IML*_*viu 52

从上面的答案阐述

WebSecurity.InitializeDatabaseConnection方法帮助指出

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

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

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

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
{
Run Code Online (Sandbox Code Playgroud)

并移入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);
    } 
}
Run Code Online (Sandbox Code Playgroud)

确保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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么决定使用DropCreateDatabaseAlways作为DB初始化程序?每次重新启动应用程序时,它都不会删除所有数据库数据吗? (2认同)
  • @Shedal - 那么你可能想尝试类似的东西:Database.SetInitializer(new MigrateDatabaseToLatestVersion <YourDbContext,Configuration>()); 其中Configuration:DbMigrationsConfiguration <YourDbContext>并有一个要覆盖的Seed方法. (2认同)

Gon*_*ing 18

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

刚刚遇到这个问题,不得不从答案+评论(+试验和错误)中取消正确的方法,所以我想分享你可以剪切和粘贴的结果.这是基于IMLiviu的答案,因此对他们充分肯定.它修改现有的UserProfileUserContext类,因为它们看起来与EF原样直接兼容:

我很惊讶地看到一个涉及完全删除数据库的建议,只是为了添加几个表,所以在阅读完所有注释并创建原型之后,这就是结果.

1 - 停止Webmatrix创建

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

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

5 - 在app start上迁移表格

现在,当应用程序启动时,您可以设置数据库初始化策略并使用以下内容触发它:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

显然,您需要添加各种using语句才能使这一切正常工作,但右键单击解析选项将为您完成.

补充说明:

如果你决定(我这样做)使用除UserProfile用户之外的表,你需要更改几个条目以匹配.

  • 在您的SimpleMembershipInitializer类中,您需要引用新的表和列名称
  • 在帐户控制器和各种登录和注册视图中,您需要引用新的模型字段(如果名称已更改)
  • UsersContext类中,您可以保留Userprofile类名,但是您需要更改Table属性以匹配您的表名.
  • UserProfile类中,您需要重命名字段以匹配新的表字段名称.
  • 在数据库中,您需要删除和之间的关系,webpages_UsersInRolesUserProfile在新用户表和webpages_UsersInRoles旧参照完整性检查之间添加关系,这将在运行时中断.(我强烈建议您删除现有的UserProfile表并检查它是否未重新创建.如果您的代码中遗留了某些内容).


CR4*_*G14 6

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