ASP.NET Identity kullanırken tablo adlarını nasıl değiştirebilirim?


213

Visual Studio 2013'ün (MSDN 2013-10-18'den indirilen) yayın sürümünü (RTM, RC değil) ve bu nedenle AspNet.Identity'nin en son (RTM) sürümünü kullanıyorum. Yeni bir web projesi oluşturduğumda, kimlik doğrulama için "Bireysel Kullanıcı Hesapları" nı seçiyorum. Bu, aşağıdaki tabloları oluşturur:

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

Yeni bir kullanıcı kaydettiğimde (varsayılan şablonu kullanarak), bu tablolar (yukarıda listelenmiştir) oluşturulur ve AspNetUsers tablosunda aşağıdakileri içeren bir kayıt bulunur:

  1. İD
  2. Kullanıcı adı
  3. PasswordHash
  4. SecurityStamp
  5. diskriminatörüyle

Ayrıca, "ApplicationUser" sınıfına ortak özellikler ekleyerek başarıyla "FirstName", "LastName", "PhoneNumber" gibi AspNetUsers tabloya ek alanlar ekledim.

İşte sorum. Yukarıdaki tabloların adlarını değiştirmenin bir yolu var mı (ilk oluşturulduğunda) veya her zaman AspNetyukarıda listelediğim gibi önekle adlandırılacak mı? Tablo adları farklı adlandırılabilirse, lütfen nasıl yapılacağını açıklayın.

-- GÜNCELLEME --

@Hao Kung'un çözümünü uyguladım. Yeni bir tablo oluşturur (örneğin buna MyUsers adını verdim), ancak yine de AspNetUsers tablosunu oluşturur. Amaç "AspNetUsers" tablosunu "MyUsers" tablosuyla değiştirmektir. Aşağıdaki koda ve oluşturulan tabloların veritabanı görüntüsüne bakın.

Aslında her AspNettabloyu kendi adımla değiştirmek istiyorum ... fxample, MyRoles, MyUserClaims, MyUserLogins, MyUserRoles ve MyUsers için.

Bunu nasıl başarabilirim ve yalnızca bir tablo kümesiyle sonuçlanabilirim?

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

Veritabanı Tabloları

- CEVAP GÜNCELLEME -

Hem Hao Kung hem de Peter Stulinski'ye teşekkürler. Bu benim sorunumu çözdü ...

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

Emin misiniz? Lütfen tüm tablolarınızı silin, _migration tablonuzu kaldırın ve ardından deneyin. Sizinkine çok benzeyen, aşağıda postaladığım kod AspNetUsers tablosunu oluşturmaz.
Piotr Stulinski

1
Kod ve benim arasındaki tek fark ben ApplicationUser "Kullanıcı" olarak yeniden adlandırılmış olmasıdır. Davranışım oldukça farklı. İlk oluşturmak o tabloları gerektiği gibi oluşturur ve belirtmek adlarla .... Belki sadece "deneme" uğruna ApplicationUser kullanıcı değiştirmek ve sonra base.OnModelCreating (modelBuilder) satırları eklemek deneyin; modelBuilder.Entity <IdentityUser> () .ToTable ("Kullanıcılar", "dbo"); modelBuilder.Entity <ApplicationUser> () .ToTable ("Kullanıcılar", "dbo");
Piotr Stulinski

1
Yukarıda güncellenen çözüm ...
user2315985

6
@Daskul ModelBuilder.Entity <IdentityUser> () .ToTable ("MyUsers"). Özellik (p => p.Id) .HasColumnName ("UserId"); bu durumda Ayırıcı sütunu MyUsers tablosuna eklenmez. Daha fazla bilgi için bu hatayı görün: stackoverflow.com/questions/22054168/…
Sergey

1
@ user2315985 - modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");@Sergey tarafından belirtilen satırı kaldırmak için cevabınızı güncellemelisiniz . Aksi takdirde, yeni adlandırılan MyUserstabloda @Daskul'un işaret ettiği gibi bir ayırıcı sütun bulunur. Ayrıca, MyUserClaims@Matt Overall'ın işaret ettiği gibi tablo yapınız yanlış olacaktır. Ben ekleme fikri bir msdn blogunda @Giang bir yorum geldi , ama onun yanlış!
kimbaudi

Yanıtlar:


125

Bunu, IdentityModel.cs dosyasını aşağıdaki gibi değiştirerek kolayca yapabilirsiniz:

DbContext'inizde OnModelCreating'i geçersiz kılın ve ardından aşağıdakileri ekleyin, bu AspNetUser tablosunu "Kullanıcılar" olarak değiştirecektir. Ayrıca varsayılan Kimlik sütununun User_Id olacağı alan adlarını da değiştirebilirsiniz.

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

veya tüm standart sütun adlarını korumak istiyorsanız aşağıdakileri yapmanız yeterlidir:

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

Aşağıda tam örnek (bu IdentityModel.cs dosyanızda olmalıdır) ben UserUser olarak adlandırılacak ApplicationUser sınıf değiştirdi.

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

Geçerli tablo varsa bu çalışmayı başaramadı lütfen unutmayın. Ayrıca hangi sütunları eşlemediğiniz varsayılan sütunların oluşturulacağını unutmayın.

Umarım yardımcı olur.


2
Bu değişikliklerin etkili olması için değişiklikleri mevcut veritabanına aktarmak üzere taşıma işlemlerini kullanmanız gerekir.
Lukasz

2
Bunu yaparsanız, yabancı anahtarlarınız biraz tuhaf olacak, IdentityUser'da tablo adını değiştirmeniz gerektiğini düşünmüyorum. Bu SO
Matt Genel

Bu daha önce beni yakaladığı gibi ekstra bir kontrol. base.OnModelCreatingGeçersiz kılmadaki çağrının kodun ilk satırı olduğundan emin olun, aksi takdirde satırların geri kalanı temel Kimlik sınıfı tarafından yazılır.
DavidG

@DavidG Teşekkür ederim
SA

Güzel çözüm. Ancak IdentityUser için tablo adının üzerine yazmak gerekli değildir. Bu çözüme bakın stackoverflow.com/questions/28016684/…
EJW

59

Çalışma çözümüm aşağıdadır:

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

Bkz bu Daha fazla ayrıntı için


Bunu (çirkin) akıcı api yerine nitelikler belirterek yapabilir misiniz?
Mariusz Jamro

Bir şekilde bu cevabı düşürmeyi başardım ve fark etmedim gibi küçük bir düzenleme yaptım! Ayrıca bu gibi bağlantılar için tercih edilen yöntemi kullanmak üzere güncelledi[text](link)
DavidG

Boş bir MVC projesi oluşturdum, 1 kez çalıştırdım ve asp adlı tablolar oluşturuldum. Daha sonra bu küçük değişikliği ekledim, tüm tablolarımı ve geçiş klasörünü sildim (değeri için) ve kodumu tekrar çalıştırdım, ancak tabloların yeniden adlandırılmasını reddetti. Daha sonra tamamen yeni bir proje yarattım, çalıştırmadan önce bu değişikliği yaptım ve şimdi çalışıyor. Çok açık bir şey mi kaçırıyorum ??
mathkid91

15

Seçtiğiniz bir tabloyla eşleştirmek için DbContext sınıfınızda bu yöntemi geçersiz kılmayı deneyebilirsiniz:

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

7
Aramayı unutmayın base.OnModelCreating(modelBuilder);, aksi takdirde modelin geri kalanı oluşturulmaz.
Ferruccio

@Hao Kung'un çözümünü uyguladıktan sonra sorumu güncelledim ama sorun devam ediyor, lütfen yukarıda düzenlenmiş soruma bakın. Teşekkürler.
user2315985

1

Ayrıca yapılandırma sınıfları oluşturabilir ve Identity sınıflarınızın her birinin her ayrıntısını belirtebilirsiniz, örneğin:

using System.Data.Entity.ModelConfiguration;

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

Ve sonra bu yapılandırmaları OnModelCreating () yöntemine ekleyin:

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

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

Bu size Kimlik sınıflarının her yönü üzerinde tam kontrol sağlayacaktır.


1

Sadece dokümantasyon amacıyla, gelecek yıllarda yıllar boyunca bu gönderiye gelen kişi için (benim XD gibi), Yorumumdan verilen tüm cevaplar doğru, ancak blogunda Alexandru Bucur tarafından verilen bu yöntemle basitçe doğrulayabilirsiniz.

         //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 Identity default tablo adlarını şu şekilde değiştirebiliriz:

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

Ayrıca her sınıfı genişletebilir ve 'IdentityUser', 'IdentityRole', gibi sınıflara herhangi bir özellik ekleyebiliriz ...

    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
}

Zaman kazanmak için AspNet Identity 2.0 Genişletilebilir Proje Şablonu'nu kullanarak tüm sınıfları genişletebiliriz.


0

Ancak .NET CORE'da (MVC 6) çalışmaz, çünkü bağlayıcıyı değiştirmemiz gerekir

sevmek

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

Birine yardımcı olabilir :)


Bu önce kod hem de önce veritabanı için çalışır?
liang

Ben ilk önce veritabanı için denedim ama model ve veritabanı aynı olması gerekir sanırım.
dnxit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.