使用 ASP.NET Identity 时如何更改表名?
Posted
技术标签:
【中文标题】使用 ASP.NET Identity 时如何更改表名?【英文标题】:How can I change the table names when using ASP.NET Identity? 【发布时间】:2013-10-27 22:19:36 【问题描述】:我正在使用 Visual Studio 2013 的发布版本(RTM,而不是 RC)(从 MSDN 2013-10-18 下载),因此是 AspNet.Identity 的最新 (RTM) 版本。当我创建一个新的 Web 项目时,我选择“个人用户帐户”进行身份验证。这将创建以下表格:
-
AspNetRoles
AspNetUserClaims
AspNetUserLogins
AspNetUserRoles
AspNet 用户
当我注册一个新用户(使用默认模板)时,这些表(上面列出的)被创建,并且 AspNetUsers 表插入了一条记录,其中包含:
-
身份证
用户名
密码哈希
安全印章
鉴别器
此外,通过向“ApplicationUser”类添加公共属性,我已成功向 AspNetUsers 表添加了其他字段,例如“FirstName”、“LastName”、“PhoneNumber”等。
这是我的问题。有没有办法更改上述表的名称(当它们首次创建时),或者它们是否总是以我上面列出的 AspNet
前缀命名?如果表名可以不同,请说明如何命名。
-- 更新--
我实现了@Hao Kung 的解决方案。它确实创建了一个新表(例如我称之为 MyUsers),但它仍然创建了 AspNetUsers 表。目标是用“MyUsers”表替换“AspNetUsers”表。请参阅下面的代码和创建的表的数据库图像。
我实际上想用我自己的名字替换每个 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");
-- 更新答案--
感谢 Hao Kung 和 Peter Stulinski。这解决了我的问题...
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 表。 您的代码和我的代码之间的唯一区别是我将 ApplicationUser 重命名为“User”。我的行为完全不同。在第一次创建时,它根据需要创建表并使用我指定的名称....也许只是为了“实验”尝试将 ApplicationUser 更改为 User 然后添加行 base.OnModelCreating(modelBuilder); modelBuilder.EntitymodelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
的行。否则,正如@Daskul 指出的那样,新命名的MyUsers
表有一个鉴别器列。此外,@Matt 总体指出,您的 MyUserClaims
表结构将是错误的。我认为添加的想法来自@Giang 在msdn blog 中的评论,但这是错误的!
【参考方案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));
【讨论】:
当您想更改所有表名时,我认为这是一个很好的答案。我会在 SetTableName 方法中做一个非常小的更改并添加一个前缀,例如;entityType.SetTableName(newTableNamePrefix + tableName.Substring(6));
也会有用的【参考方案2】:
但它在 .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");
);
它可能会帮助某人:)
【讨论】:
这对代码优先和数据库优先都有效吗? 我没有先尝试数据库,但我想如果模型和数据库相同,它应该可以工作。【参考方案3】:您还可以创建配置类并指定每个身份类的每个细节,例如:
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());
...
这将使您可以完全控制身份类的各个方面。
【讨论】:
【参考方案4】:我们可以像这样更改 asp.net Identity 默认表名:
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 Extensible Project Template 来扩展所有类。
【讨论】:
【参考方案5】:以下是我的工作解决方案:
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();
详情请见this
【讨论】:
你能通过指定属性而不是(丑陋的)流利的 api 来做到这一点吗? 做了一个小的编辑,因为我设法否决了这个答案并且没有注意到!还更新了它以使用像这样的链接的首选方法[text](link)
我创建了一个空的 MVC 项目,运行了 1 次,创建了 asp 命名的表。然后我添加了这个小改动,删除了我所有的表和迁移文件夹(为了它的价值)并再次运行我的代码,但表拒绝被重命名。然后我创建了一个全新的项目,在运行之前进行了这个更改,现在它可以工作了。我是否遗漏了一些非常明显的东西??【参考方案6】:
您可以通过如下修改 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");
请注意,如果当前表存在,我还没有设法让它工作。另请注意,您未映射默认列的任何列都将被创建。
希望对您有所帮助。
【讨论】:
要使这些更改生效,您需要使用迁移将更改推送到现有数据库。 如果你这样做,你的外键会有点奇怪,我认为你不需要更改 IdentityUser 上的表名。看到这个SO post 这就像一个额外的检查,因为这让我之前发现了。确保对base.OnModelCreating
的调用是覆盖中的第一行代码,否则其余行将被基 Identity 类覆盖。
@DavidG 谢谢你
很好的解决方案。但不必覆盖 IdentityUser 的表名。请参阅此解决方案***.com/questions/28016684/…【参考方案7】:
您可以尝试在您的 DbContext 类中覆盖此方法以将其映射到您选择的表:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<IdentityUser>()
.ToTable("AspNetUsers");
【讨论】:
别忘了调用base.OnModelCreating(modelBuilder);
否则模型的其余部分将不会创建。
我在实施@Hao Kung 的解决方案后更新了我的问题,但问题仍然存在,请参阅上面我编辑的问题。谢谢。以上是关于使用 ASP.NET Identity 时如何更改表名?的主要内容,如果未能解决你的问题,请参考以下文章