Bagaimana saya bisa mengubah nama tabel saat menggunakan ASP.NET Identity?

213

Saya menggunakan versi rilis (RTM, bukan RC) dari Visual Studio 2013 (diunduh dari MSDN 2013-10-18) dan karena itu versi AspNet.Identity (RTM) terbaru. Ketika saya membuat proyek web baru, saya memilih "Akun Pengguna Individual" untuk otentikasi. Ini menciptakan tabel berikut:

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

Ketika saya mendaftarkan pengguna baru (menggunakan templat default), tabel ini (tercantum di atas) dibuat dan tabel AspNetUsers memiliki catatan yang dimasukkan yang berisi:

  1. Indo
  2. Nama pengguna
  3. Kata sandi
  4. SecurityStamp
  5. Diskriminator

Selain itu, dengan menambahkan properti publik ke kelas "ApplicationUser" Saya telah berhasil menambahkan bidang tambahan ke tabel AspNetUsers, seperti "FirstName", "LastName", "PhoneNumber", dll.

Inilah pertanyaan saya. Apakah ada cara untuk mengubah nama tabel di atas (saat pertama kali dibuat) atau akankah mereka selalu dinamai dengan AspNetawalan seperti yang saya sebutkan di atas? Jika nama tabel dapat dinamai berbeda, tolong jelaskan caranya.

- PEMBARUAN -

Saya menerapkan solusi @ Hua Kung. Itu membuat tabel baru (misalnya saya menyebutnya MyUsers), tetapi juga masih membuat tabel AspNetUsers. Tujuannya adalah untuk mengganti tabel "AspNetUsers" dengan tabel "MyUsers". Lihat kode di bawah ini dan gambar database dari tabel yang dibuat.

Saya sebenarnya ingin mengganti masing-masing AspNet tabel dengan nama saya sendiri ... Untuk fxample, MyRoles, MyUserClaims, MyUserLogins, MyUserRoles, dan MyUsers.

Bagaimana saya mencapai ini dan berakhir dengan hanya satu set tabel?

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

Tabel Database

- JAWABAN TERBARU -

Terima kasih untuk Hao Kung dan Peter Stulinski. Ini menyelesaikan masalah saya ...

    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");
    }
pengguna2315985
sumber
Apakah kamu yakin Hapus semua tabel Anda, hapus tabel _migrasi Anda dan kemudian coba. Kode yang saya posting di bawah ini yang sangat mirip dengan Anda tidak membuat tabel AspNetUsers.
Piotr Stulinski
1
Satu-satunya perbedaan antara kode Anda dan kode saya adalah saya mengganti nama ApplicationUser menjadi "Pengguna". Perilaku saya sangat berbeda. Pada awalnya buat itu membuat tabel sesuai kebutuhan dan dengan nama yang saya tentukan .... Mungkin hanya untuk "eksperimen", coba ubah ApplicationUser ke Pengguna dan kemudian tambahkan basis baris. OnModelCreating (modelBuilder); modelBuilder.Entity <IdentityUser> () .ToTable ("Pengguna", "dbo"); modelBuilder.Entity <ApplicationUser> () .ToTable ("Pengguna", "dbo");
Piotr Stulinski
1
Solusi yang diperbarui di atas ...
user2315985
6
@Daskul Hapus modelBuilder.Entity <IdentityUser> () .ToTable ("MyUsers"). Properti (p => p.Id) .HasColumnName ("UserId"); dan dalam hal itu kolom pembeda tidak akan ditambahkan ke tabel MyUsers. Lihat kesalahan ini untuk info lebih lanjut: stackoverflow.com/questions/22054168/…
Sergey
1
@ user2315985 - Anda harus memperbarui jawaban Anda untuk menghapus baris yang mengandung modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");seperti yang disebutkan oleh @Sergey. Jika tidak, MyUserstabel yang baru bernama memiliki kolom diskriminator seperti yang ditunjukkan @Daskul. Selain itu, MyUserClaimsstruktur tabel Anda akan salah seperti yang ditunjukkan oleh @Matt Keseluruhan. Saya pikir ide untuk menambahkan berasal dari komentar ke @iang di blog msdn , tapi itu salah!
kimbaudi

Jawaban:

125

Anda dapat melakukan ini dengan mudah dengan memodifikasi IdentityModel.cs seperti di bawah ini:

Override OnModelCreating di DbContext Anda lalu tambahkan berikut ini, ini akan mengubah tabel AspNetUser menjadi "Pengguna" Anda juga dapat mengubah nama bidang kolom Id default akan menjadi User_Id.

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

atau cukup di bawah ini jika Anda ingin menyimpan semua nama kolom standar:

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

Contoh lengkap di bawah ini (ini harus dalam file IdentityModel.cs Anda) saya mengubah kelas ApplicationUser saya untuk disebut Pengguna.

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

Harap dicatat saya belum berhasil membuat ini berfungsi jika tabel saat ini ada. Perhatikan juga kolom apa pun yang tidak Anda petakan yang akan dibuat.

Semoga itu bisa membantu.

Piotr Stulinski
sumber
2
Untuk membuat perubahan ini berlaku, Anda perlu menggunakan migrasi untuk mendorong perubahan ke database yang ada.
Lukasz
2
Jika Anda melakukan ini, kunci asing Anda akan sedikit aneh, saya rasa Anda tidak perlu mengubah nama tabel di IdentityUser. Lihat pos SO
Matt Keseluruhan
Sama seperti pemeriksaan tambahan karena ini membuat saya keluar sebelumnya. Pastikan panggilan ke base.OnModelCreatingadalah baris kode pertama dalam override jika tidak, baris lainnya ditimpa oleh kelas Identity dasar.
DavidG
@ David G Terima kasih memang
SA
Solusi yang bagus Tetapi tidak perlu menimpa nama tabel untuk IdentityUser. Lihat solusi ini stackoverflow.com/questions/28016684/…
EJW
59

Di bawah ini adalah solusi kerja saya:

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

Lihat ini untuk detail lebih lanjut

Frank Myat Thu
sumber
Bisakah Anda melakukannya dengan menentukan atribut alih-alih api fasih (jelek)?
Mariusz Jamro
Membuat perubahan kecil karena entah bagaimana saya berhasil mengunggah jawaban ini dan tidak memperhatikan! Juga perbarui untuk menggunakan metode yang disukai untuk tautan seperti ini[text](link)
DavidG
Saya membuat proyek MVC kosong, menjalankannya 1 kali, dan tabel bernama asp dibuat. Kemudian saya menambahkan perubahan kecil ini, menghapus semua tabel dan folder migrasi saya (untuk apa nilainya) dan menjalankan kode saya lagi, tetapi tabel menolak untuk diganti namanya. Saya kemudian membuat proyek yang sama sekali baru, membuat perubahan ini sebelum berjalan, dan sekarang berfungsi. Apakah saya melewatkan sesuatu yang sangat jelas ??
mathkid91
15

Anda dapat mencoba mengganti metode ini di kelas DbContext Anda untuk memetakannya ke tabel yang Anda pilih:

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<IdentityUser>()
            .ToTable("AspNetUsers");
Hao Kung
sumber
7
Jangan lupa menelepon base.OnModelCreating(modelBuilder);atau sisa model tidak akan dibuat.
Ferruccio
Saya memperbarui pertanyaan saya setelah menerapkan solusi @ Hua Kung tetapi masalahnya tetap ada, lihat pertanyaan saya yang diedit di atas. Terima kasih.
user2315985
1

Anda juga dapat membuat kelas konfigurasi dan menentukan setiap detail dari masing-masing kelas Identitas Anda, misalnya:

using System.Data.Entity.ModelConfiguration;

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

Dan kemudian sertakan konfigurasi ini dalam metode OnModelCreating ():

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

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

Ini akan memberi Anda kontrol penuh atas setiap aspek dari kelas Identitas.

Manish
sumber
1

Hanya untuk keperluan dokumentasi, untuk orang yang datang ke posting ini pada tahun-tahun sebelumnya, (seperti saya XD), Semua jawaban yang diberikan komentar saya benar, tetapi Anda dapat dengan mudah menemukan metode ini yang diberikan oleh Alexandru Bucur di blog-nya

         //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));
            }
        }
sgrysoft
sumber
0

Kami dapat mengubah nama tabel standar asp.net Identity seperti ini:

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

Selain itu kami dapat memperluas setiap kelas dan menambahkan properti apa pun ke kelas seperti '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
}

Untuk menghemat waktu, kita dapat menggunakan AspNet Identity 2.0 Extensible Project Template untuk memperluas semua kelas.

Arvand
sumber
0

Tapi itu tidak berfungsi di .NET CORE (MVC 6) untuk itu kita perlu mengubah ikatan

Suka

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

Mungkin membantu seseorang :)

dnxit
sumber
apakah ini berfungsi baik untuk kode-pertama dan basis data-pertama?
liang
Saya belum mencoba untuk basis data terlebih dahulu tetapi saya kira itu akan berhasil jika model dan basis data sama.
dnxit