14

ASP.NET 3 IDを見ると、stringが使用され、一意のプライマリキーにはGuidは使用されません。私Entity Frameworkcode firstユーザーのApplicationUserクラスでEF-CoreでID /プライマリキーにStringの代わりにGuidを使用する方法

は、私は私のEntity Frameworkのは、テーブルaspnetusersではなくuniqueidentifier

nvarchar(450)のキータイプを使用して作成ばかりの移行を作成するとき、その結果Identityクラス

public class ApplicationUser : IdentityUser 
{ 
} 

に継承します

これをASP.NET Identity 2ENtity Frameworkプロジェクトと比較すると、IDフィールドがuniqueidentifierで、nvarchar(450)

ではありません

私はASP.NET Identity 3持つ一意のキーの代わりにstringGuiduniqueidentifierの代わりnvarchar(450)に使用する方法はありnvarchar(450)

よりも良いだろう、データベースのパフォーマンスの主キーとuniqueidentifierの外部キーのために想像するでしょうか?

previous question StringをGuidに変換する方法がありますが、データベーステーブルIdをGuidにしたいとします。

長さがnvarchar(128)の場合は、前のBETAと同じように別のものが見つかりました。理由はすべてのデータベースがGuidをサポートしているわけではなく、柔軟性のために変更されているからです。

identity 3全体を書き換えることなく、文字列からGuidに簡単に変更する必要がありますか?

nvarchar(450)は実際には過剰ですが、SQL Serverデータベースの制約を作成する際には、あらゆる種類の警告が表示されます。データベース管理者は、これらの警告を確実に気に入らないでしょう。

答えて

30

カスタムApplicationUserIdentityUser<TKey>から継承し、カスタムロールを必要とするがIdentityDbContext<ApplicationUser, Role, TKey>から継承し、GUIDキーを自動生成するために流暢なAPIを使用しIdentityRole<TKey>

public class ApplicationUser : IdentityUser<Guid> { }  
public class Role : IdentityRole<Guid> { } 

からカスタムコンテキストクラスを継承します。

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, Guid> 
{ 
    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 

     builder.Entity<ApplicationUser>(b => 
     { 
      b.Property(u => u.Id).HasDefaultValueSql("newsequentialid()"); 
     }); 

     builder.Entity<Role>(b => 
     { 
      b.Property(u => u.Id).HasDefaultValueSql("newsequentialid()"); 
     }); 
    } 
} 

[スタートアップにデータベースを作成していない場合、この

services.AddIdentity<ApplicationUser, Role>() 
     .AddEntityFrameworkStores<ApplicationDbContext, Guid>() 
     .AddDefaultTokenProviders() 
     .AddUserStore<UserStore<ApplicationUser, Role, ApplicationDbContext, Guid>>() 
     .AddRoleStore<RoleStore<Role, ApplicationDbContext, Guid>>(); 

のようにコンテナにアイデンティティサービスを追加し、移行フォルダをクリアし、EFを実行していることに、注意してください

+0

コマンドEntityFramework 7/EntiryFramework Core 1.0のバグ.rc1-finalまで、外来キーでジェネリックを使用するときにマイグレーションを中断します。組み込み型(Guidのような)では閉じられません。これはrc2-nightliesでかなりの間修正されていますが、まだリリースされていません。 https://github.com/aspnet/EntityFramework/issues/3545 – Tseng

2

ApplicationUserは、IdentityUserから継承します。これは、文字列がidであると定義されています。したがって、実際にguid/uniqueidentifierを使用するには、その基本クラスから継承しない必要があります。

内部的にはIDにguid文字列を使用していることに注意してください。ここに示したようにあなたは、少なくともキーのフィールドのサイズを制限することができるはずです。

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 

     builder.Entity<ApplicationUser>(b => 
     { 
      // you could limit the field size to just long enough for a guid id as string 
      b.Property(p => p.Id) 
       .HasMaxLength(36); 

      // instead, you could define the id as Guid but more work required 
      //b.Property(p => p.Id) 
      // .ForSqlServerHasColumnType("uniqueidentifier") 
      // .ForSqlServerHasDefaultValueSql("newid()") 
      // .IsRequired(); 

     }); 

    } 
} 

キーのGUID/UNIQUEIDENTIFIERを使用することが可能であるが、それはより多くの作業が必要になり、独自のベースを使用することに加えて、 (または基本クラスをまったく使用しない)、カスタムDbContextを使用してモデルをマップします。インターフェイスIUserStoreは文字列でFindByIdメソッドのシグネチャを定義しているため、EF code from hereを借用して変更すると、あなたは動くはずです。UserStoreから継承し、idでユーザーを検索する仮想メソッドをオーバーライドする必要があります。だからあなたはあなたがフェッチする必要があるか、idで見つける必要があるメソッド内の文字列をguidに変換する必要がありますオーバーライド。私はまさにそのアイデンティティ

EDITのカスタムマルチテナント実装を持っている私のcloudscribe projectでやってる

:実際IdentityUserはあなたがキーのタイプを定義することができ、一般的なバージョンを持って近づいコードを見ます

public class IdentityUser<TKey> where TKey : IEquatable<TKey> 

だから、あなただけの

IdentityUser<Guid> 

のように、独自の基本クラスを定義することができるかもしれませんが、私はまだだと思いますidストリングを取得し、そのストリングをguidに変換するUserStoreメソッドをオーバーライドする必要があります。

9

ASP.NET ID v3はv2よりもはるかに拡張性がありましたが、この例の移行はまだまだ困難でした(いくつかの調整が必要かもしれません)。

以下は同様にユーザーとロールのGUID主キーに基づいて、あなたのアイデンティティストアを与える必要があります:あなたがしなかった場合は、

services.AddIdentity<ApplicationUser, IdentityRole<Guid>>(
      identity => 
      { 
       // whatever identity options you want 
       identity.User.RequireUniqueEmail = true; 
       identity.Password.RequiredLength = 8; 
      }). 
      AddEntityFrameworkStores<GuidDataContext, Guid>().AddDefaultTokenProviders(); 

同様に:

public class ApplicationUser : IdentityUser<Guid> 
{ 
} 

public class GuidDataContext : 
    IdentityDbContext<ApplicationUser, IdentityRole<Guid>, Guid> 
{ 
} 

とスタートアップクラスでアイデンティティユーザーにカスタムフィールドを追加するか、オプションをカスタマイズする必要がある場合は、次のようにします。

public class GuidDataContext : 
    IdentityDbContext<IdentityUser<Guid>, IdentityRole<Guid>, Guid> 
{ 
} 

と、起動中:

services 
    .AddIdentity<IdentityUser<Guid>, IdentityRole<Guid>>() 
    .AddEntityFrameworkStores<GuidDataContext, Guid>() 
    .AddDefaultTokenProviders(); 
関連する問題