簡體   English   中英

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

[英]How can I change the table names when using ASP.NET Identity?

我使用的是 Visual Studio 2013(從 MSDN 2013-10-18 下載)的發布版本(RTM,而不是 RC),因此是 AspNet.Identity 的最新 (RTM) 版本。 當我創建一個新的 Web 項目時,我選擇“個人用戶帳戶”進行身份驗證。 這將創建下表:

  1. AspNet角色
  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 表。 目標是用“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");
    }

您可以通過按照以下方式修改 IdentityModel.cs 來輕松完成此操作:

在您的 DbContext 中覆蓋 OnModelCreating 然后添加以下內容,這會將 AspNetUser 表更改為“用戶”,您還可以更改默認 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");
        }
    }

請注意,如果當前表存在,我還沒有設法讓它工作。 另請注意,您未映射的任何列都會創建默認列。

希望有幫助。

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

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();
    }
}

請參閱了解更多詳情

您可以嘗試在 DbContext 類中覆蓋此方法以將其映射到您選擇的表:

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

僅出於文檔目的,對於那些在未來幾年中看到這篇文章的人(如我 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));
            }
        }

也可以動態執行,如下所示:

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options):  base(options)
    {
    }

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

        var entityTypes = builder.Model.GetEntityTypes(); 
        foreach (var entityType in entityTypes)
            builder.Entity(entityType.ClrType)
                   .ToTable(entityType.GetTableName().Replace("AspNet", ""));
    }

}

我們可以像這樣更改 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 可擴展項目模板來擴展所有類。

您還可以創建配置類並指定每個 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 類的各個方面。

但它在 .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");
    });
}

它可能會幫助某人:)

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<AppUser>().ToTable("Users");
            modelBuilder.Entity<IdentityUser>().ToTable("Users");
            modelBuilder.Entity<IdentityRole>().ToTable("Role");
            modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRole");
            modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim");
            modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin");
        }

對於 .net 6,您需要使用 Duende.IdentityServer.EntityFramework.Entities

        protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUser>().ToTable("SecurityUsers");  
        modelBuilder.Entity<IdentityRole>().ToTable("SecurityRole");
        modelBuilder.Entity<IdentityUserRole<string>>().ToTable("SecurityUserRole");
        modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("SecurityUserClaim");
        modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("SecurityUserLogin");
        modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("SecurityRoleClaims");
        modelBuilder.Entity<IdentityUserToken<string>>().ToTable("SecurityUserTokens");

        modelBuilder.Entity<Duende.IdentityServer.EntityFramework.Entities.PersistedGrant>().ToTable("SecurityPersistedGrant");
        modelBuilder.Entity<Duende.IdentityServer.EntityFramework.Entities.Key>().ToTable("SecurityKey");
        modelBuilder.Entity<Duende.IdentityServer.EntityFramework.Entities.DeviceFlowCodes>().ToTable("SecurityDeviceCode");

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM