使用ASP.NET Identity时如何更改表名称?


213

我正在使用Visual Studio 2013的发行版(RTM,而不是RC)(从MSDN 2013-10-18下载),因此使用的是AspNet.Identity的最新(RTM)版本。创建新的Web项目时,我选择“个人用户帐户”进行身份验证。这将创建下表:

  1. AspNetRoles
  2. AspNetUserClaims
  3. AspNetUserLogins
  4. AspNetUserRoles
  5. AspNetUsers

当我注册新用户(使用默认模板)时,将创建这些表(上面列出),并且AspNetUsers表插入了一条记录,其中包含:

  1. ID
  2. 用户名
  3. 密码哈希
  4. 安全邮票
  5. 鉴别器

此外,通过将公共属性添加到“ ApplicationUser”类,我已成功将其他字段添加到AspNetUsers表中,例如“ FirstName”,“ LastName”,“ PhoneNumber”等。

这是我的问题。有没有办法更改上述表的名称(首次创建时),还是总是使用AspNet上面列出的前缀来命名它们?如果可以使用不同的名称命名表,请说明如何使用。

-更新-

我实现了@Hao Kung的解决方案。它的确创建了一个新表(例如,我称其为MyUsers),但它仍然创建了AspNetUsers表。目标是将“ AspNetUsers”表替换为“ MyUsers”表。请参见下面的代码和所创建表的数据库图像。

我实际上想AspNet用我自己的名称替换每个表...对于fxample,MyRoles,MyUserClaims,MyUserLogins,MyUserRoles和MyUsers。

我该如何做到这一点并最终只得到一组表?

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string PhonePrimary { get; set; }
    public string PhoneSecondary { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(): base("DefaultConnection")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUser>().ToTable("MyUsers");
    }
}

数据库表

-更新答案-

感谢郝Ha和彼得·史蒂林斯基。这解决了我的问题...

    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
        modelBuilder.Entity<ApplicationUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
        modelBuilder.Entity<IdentityUserRole>().ToTable("MyUserRoles");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("MyUserLogins");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("MyUserClaims");
        modelBuilder.Entity<IdentityRole>().ToTable("MyRoles");
    }

你确定吗?请删除所有表,删除_migration表,然后尝试。我在下面发布的代码与您的代码非常相似,不会创建AspNetUsers表。
Piotr Stulinski

1
您的代码和我的代码之间的唯一区别是,我将ApplicationUser重命名为“ User”。我的行为完全不同。第一次创建时,它会根据需要并使用我指定的名称来创建表。也许只是出于“实验”的缘故,请尝试将ApplicationUser更改为User,然后添加base.OnModelCreating(modelBuilder)行。modelBuilder.Entity <IdentityUser>().ToTable(“ Users”,“ dbo”); modelBuilder.Entity <ApplicationUser>().ToTable(“ Users”,“ dbo”);
Piotr Stulinski 2013年

1
上面更新的解决方案...
2013年

6
@Daskul删除modelBuilder.Entity <IdentityUser>()。ToTable(“ MyUsers”)。Property(p => p.Id).HasColumnName(“ UserId”); 在这种情况下,鉴别符列将不会添加到MyUsers表中。出现这种错误的详细信息: stackoverflow.com/questions/22054168/...
谢尔盖·

1
@ user2315985-您应该更新您的答案以删除包含modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");@Sergey提到的行。否则,MyUsers正如@Daskul指出的那样,新命名的表具有一个鉴别符列。另外,MyUserClaims正如@Matt总体指出的那样,您的表结构将是错误的。我认为要添加的想法来自msdn博客中对@Giang的评论,但这是错误的!
kimbaudi

Answers:


125

您可以按照以下说明修改IdentityModel.cs轻松完成此操作:

在您的DbContext中重写OnModelCreating,然后添加以下内容,这会将AspNetUser表更改为“ Users”,您还可以更改字段名称,默认的Id列将变为User_Id。

modelBuilder.Entity<IdentityUser>()
                    .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");

如果您想保留所有标准列名称,则仅显示以下内容:

modelBuilder.Entity<IdentityUser>()
                        .ToTable("Users", "dbo")

下面的完整示例(应在您的IdentityModel.cs文件中)我将ApplicationUser类更改为User。

public class User : IdentityUser
    {
        public string PasswordOld { get; set; }
        public DateTime DateCreated { get; set; }

        public bool Activated { get; set; }

        public bool UserRole { get; set; }

    }

public class ApplicationDbContext : IdentityDbContext<User>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<IdentityUser>()
                .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
            modelBuilder.Entity<User>()
                .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
        }
    }

请注意,如果当前表存在,我尚未设法使它正常工作。还要注意,无论您未映射的列如何,都会创建默认列。

希望能有所帮助。


2
为了使这些更改生效,您需要使用迁移将更改推送到现有数据库。
2014年

2
如果这样做,您的外键会有点奇怪,我认为您不需要更改IdentityUser上的表名。看到这样的帖子
Matt整体

就像另外一张支票一样,这使我以前很困惑。确保对的调用base.OnModelCreating是重写中的第一行代码,否则其余的行将被基础Identity类覆盖。
DavidG

@DavidG的确如此谢谢
SA

好的解决方案。但是不必覆盖IdentityUser的表名。请参阅此解决方案stackoverflow.com/questions/28016684/…–
EJW

59

以下是我的工作解决方案:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder); // This needs to go before the other rules!

        modelBuilder.Entity<ApplicationUser>().ToTable("User");
        modelBuilder.Entity<IdentityRole>().ToTable("Role");
        modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

看到这个更多的细节


您可以通过指定属性而不是(难看的)流利的api来做到这一点吗?
Mariusz Jamro '16

进行了较小的编辑,因为我设法以某种方式否决了这个答案,并且没有注意到!还对其进行了更新,以将首选方法用于此类链接[text](link)
DavidG '16

我创建了一个空的MVC项目,运行了1次,并创建了以asp命名的表。然后,我添加了这个较小的更改,删除了我所有的表和迁移文件夹(按其价值计算),然后再次运行了我的代码,但是表拒绝重命名。然后,我创建了一个全新的项目,在运行之前进行了更改,现在可以正常工作了。我错过了很明显的东西吗?
mathkid91

15

您可以尝试在DbContext类中重写此方法,以将其映射到您选择的表:

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<IdentityUser>()
            .ToTable("AspNetUsers");

7
不要忘记打电话,base.OnModelCreating(modelBuilder);否则将不会创建模型的其余部分。
Ferruccio

我在实施@Hao Kung的解决方案后更新了问题,但问题仍然存在,请参阅上面的修改后问题。谢谢。
2013年

1

您还可以创建配置类并指定每个Identity类的每个细节,例如:

using System.Data.Entity.ModelConfiguration;

public class ApplicationUserConfig : EntityTypeConfiguration<ApplicationUser>
{
    public UserConfig()
    {
        ToTable("Users");
        Property(u => u.LocationName).IsRequired();
    }
}

然后将这些配置包含在OnModelCreating()方法中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new ApplicationUserConfig());
        ...
    }

这将使您可以完全控制Identity类的各个方面。


1

仅出于文档目的,对于未来几年来写这篇文章的人(如我XD),我评论中给出的所有答案都是正确的,但是您可以使用Alexandru Bucur在他的博客上给出的这种方法来简单地确定。

         //But this method is not longer supported on netcore > 2.2, so I need to fix it
         foreach (var entityType in modelBuilder.Model.GetEntityTypes())
         {
            var table = entityType.Relational().TableName;
             if (table.StartsWith("AspNet"))
             {
                 entityType.Relational().TableName = table.Substring(6);
             }
         };

        //This is the functional way on NetCore > 2.2
        foreach (var entityType in modelBuilder.Model.GetEntityTypes())
        {
            var tableName = entityType.GetTableName();
            if (tableName.StartsWith("AspNet"))
            {
                entityType.SetTableName(tableName.Substring(6));
            }
        }

0

我们可以像这样更改asp.net身份默认表名称:

    public class ApplicationDbContext : IdentityDbContext
    {    
        public ApplicationDbContext(): base("DefaultConnection")
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<IdentityUser>().ToTable("user");
            modelBuilder.Entity<ApplicationUser>().ToTable("user");

            modelBuilder.Entity<IdentityRole>().ToTable("role");
            modelBuilder.Entity<IdentityUserRole>().ToTable("userrole");
            modelBuilder.Entity<IdentityUserClaim>().ToTable("userclaim");
            modelBuilder.Entity<IdentityUserLogin>().ToTable("userlogin");
        }
    }

此外,我们可以扩展每个类,并向'IdentityUser','IdentityRole',...等类添加任何属性。

    public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
{
    public ApplicationRole() 
    {
        this.Id = Guid.NewGuid().ToString();
    }

    public ApplicationRole(string name)
        : this()
    {
        this.Name = name;
    }

    // Add any custom Role properties/code here
}


// Must be expressed in terms of our custom types:
public class ApplicationDbContext 
    : IdentityDbContext<ApplicationUser, ApplicationRole, 
    string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    static ApplicationDbContext()
    {
        Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    // Add additional items here as needed
}

为了节省时间,我们可以使用AspNet Identity 2.0可扩展项目模板来扩展所有类。


0

但这在.NET CORE(MVC 6)中不起作用,因为我们需要将绑定更改为

喜欢

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<IdentityRole>().ToTable("Role");
    builder.Entity<IdentityUser>(entity => 
    {
        entity.ToTable("User");
        entity.Property(p => p.Id).HasColumnName("UserId");
    });
}

它可能会帮助某人:)


这对于代码优先和数据库优先都有效吗?

我没有尝试过首先使用数据库,但是如果模型和数据库相同,我想应该可以使用。
dnxit '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.