ASP.NET Identityを使用しているときにテーブル名を変更するにはどうすればよいですか?


213

Visual Studio 2013(MSDN 2013-10-18からダウンロード)のリリースバージョン(RCではなくRTM)を使用しているため、AspNet.Identityの最新(RTM)バージョンを使用しています。新しいWebプロジェクトを作成するとき、認証に「個人ユーザーアカウント」を選択します。これにより、次のテーブルが作成されます。

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

(デフォルトテンプレートを使用して)新しいユーザーを登録すると、これらのテーブル(上記のリスト)が作成され、AspNetUsersテーブルに次の内容を含むレコードが挿入されます。

  1. Id
  2. ユーザー名
  3. PasswordHash
  4. SecurityStamp
  5. 弁別者

さらに、パブリックプロパティをクラス "ApplicationUser"に追加することで、 "FirstName"、 "LastName"、 "PhoneNumber"などのフィールドをAspNetUsersテーブルに追加できました。

これが私の質問です。上記のテーブルの名前を変更する方法はありますか(最初に作成されたとき)、または常にAspNet上記のようにプレフィックスが付けられますか?テーブル名に別の名前を付けることができる場合は、その方法を説明してください。

-更新-

@Hao Kungのソリューションを実装しました。新しいテーブル(たとえば、MyUsersという名前)を作成しますが、AspNetUsersテーブルも作成します。目標は、「AspNetUsers」テーブルを「MyUsers」テーブルに置き換えることです。以下のコードと作成されたテーブルのデータベースイメージを参照してください。

実際に、各AspNetテーブルを自分の名前に置き換えたい... fxample、MyRoles、MyUserClaims、MyUserLogins、MyUserRoles、MyUsersの場合。

これをどのように達成し、1つのテーブルセットのみで終了するのですか?

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テーブルを作成しません。
Piotr Stulinski 2013年

1
コードと私の唯一の違いは、ApplicationUserの名前を "User"に変更したことです。私の行動はかなり異なります。最初に作成すると、必要に応じて、指定した名前でテーブルが作成されます。多分単に「実験」のために、ApplicationUserをUserに変更して、base.OnModelCreating(modelBuilder);という行を追加してみてください。modelBuilder.Entity <IdentityUser>().ToTable( "Users"、 "dbo"); modelBuilder.Entity <ApplicationUser>().ToTable( "Users"、 "dbo");
Piotr Stulinski 2013年

1
上記の更新されたソリューション...
user2315985 2013年

6
@Daskul remove modelBuilder.Entity <IdentityUser>()。ToTable( "MyUsers")。Property(p => p.Id).HasColumnName( "UserId"); その場合、判別子列はMyUsersテーブルに追加されません。:詳細は、このエラーを参照してください stackoverflow.com/questions/22054168/...
セルゲイ

1
@ user2315985-回答を更新して、@ Sergey modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");によって言及されている行を削除する必要があります。それ以外の場合は、MyUsers@ Daskulが指摘したように、新しく名前が付けられたテーブルに識別子列があります。また、MyUserClaims@ Matt全体が指摘しているように、テーブル構造は間違っています。これを追加するアイデアは、msdnブログ@Giangへのコメントから来たと思いますが、間違っています!
kimbaudi 2016年

回答:


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
これらの変更を有効にするには、移行を使用して変更を既存のデータベースにプッシュする必要があります。
Lukasz 2014

2
これを行うと、外部キーが少し奇妙になります。IdentityUserのテーブル名を変更する必要はないと思います。このSO投稿を
マットオーバーオール

これが以前に私を見つけたのと同じように、追加のチェックと同じです。の呼び出しがbase.OnModelCreatingオーバーライドのコードの最初の行であることを確認してください。そうでない場合、残りの行は基本のIdentityクラスによって上書きされます。
DavidG 2016年

@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 2016年

どういうわけか私がこの回答に反対投票してなんとか気づかなかったので、マイナーな編集を行いました!また、このようなリンクに適した方法を使用するように更新しました[text](link)
DavidG

空のMVCプロジェクトを作成して1回実行すると、aspという名前のテーブルが作成されました。次に、この小さな変更を追加し、すべてのテーブルと移行フォルダ(その価値があるため)を削除して、コードを再度実行しましたが、テーブルの名前の変更が拒否されました。次に、完全に新しいプロジェクトを作成し、実行前にこの変更を加え、現在は機能しています。私は非常に明白な何かを見逃していますか?
mathkid91 2016年

15

DbContextクラスでこのメソッドをオーバーライドして、選択したテーブルにマッピングすることができます。

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

7
呼び出すことを忘れないでください。そうしないとbase.OnModelCreating(modelBuilder);、モデルの残りの部分は作成されません。
Ferruccio 2013年

@Hao Kungのソリューションを実装した後、質問を更新しましたが、問題は解決しません。上記の編集した質問を参照してください。ありがとう。
user2315985 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 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を使用してすべてのクラスを拡張できます。


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

それは誰かを助けるかもしれません:)


これはコードファーストとデータベースファーストの両方で機能しますか?
liang

最初にデータベースを試したことはありませんが、モデルとデータベースが同じであれば機能するはずです。
dnxit
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.