14

Wenn ich auf die ASP.NET 3-Identität schaue, verwendet es eine string und nicht eine Guid für den eindeutigen Primärschlüssel.Wie EF-Core eine Guid anstelle von String für seine ID/Primärschlüssel verwenden kann

In meinem Entity Frameworkcode firstApplicationUser Klasse Benutzer erben ich die Klasse Identität

public class ApplicationUser : IdentityUser 
{ 
} 

, die sich ergibt, wenn ich meine Entity Framework erstellen Migrationen eine Tabelle aspnetusers mit einem Schlüsseltyp nvarchar(450) statt uniqueidentifier

erstellt bekommen

Wenn ich dies mit ASP.NET Identity 2ENtity Framework Projekt vergleichen, erstellt es ein ID-Feld von uniqueidentifier und nicht nvarchar(450)

würde ich für die Performance der Datenbank Primärschlüssel und Fremdschlüssel von uniqueidentifier wäre besser als nvarchar(450)

vorstellen Gibt es eine Möglichkeit für die eindeutigen Schlüssel Guid statt string und uniqueidentifier statt nvarchar(450) mit ASP.NET Identity 3 zu bedienen?

Es gibt eine previous question wie man eine Zeichenkette in eine Guid konvertiert, aber ich möchte, dass die Datenbanktabellen-ID eine GUID ist.

fand ich eine andere question als auch für eine vorherige BETA, wenn die Länge nvarchar (128) war. Der Grund dafür ist, dass nicht alle Datenbanken Guids unterstützen und dass es aus Gründen der Flexibilität geändert wurde.

Gibt es muss eine einfache Möglichkeit, von String Guid zu ändern, ohne die ganzen identity 3 zu Umschreiben?

nvarchar(450) ist wirklich übertrieben und gibt alle Arten von Warnungen, wenn Einschränkungen SQL Server-Datenbank zu erstellen. Datenbankadministratoren werden diese Warnungen definitiv nicht mögen.

Antwort

30

Sie benötigen individuelle ApplicationUser vererben IdentityUser<TKey> und benutzerdefinierte Rolle erben von IdentityRole<TKey>

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

Benutzerdefinierte Kontext Klasse von IdentityDbContext<ApplicationUser, Role, TKey> und verwenden fließend api für Auto erzeugen guid Schlüssel erben.

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

dann in Startup hinzufügen dieser Identitätsdienst zu Container wie

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

Wenn Sie die Datenbank erstellt haben, die Migrationen Ordner löschen und führen Sie ef-Befehle

+0

Bitte beachten Sie, dass es eine Fehler in EntityFramework 7/EntiryFramework Core 1.0 bis rc1-final, der Migrationen bei der Verwendung von Generics in Fremdschlüsseln unterbricht, die nicht über die integrierten Typen (wie Guid) geschlossen sind. Dies ist seit einiger Zeit in rc2-Nightlies behoben, aber es ist noch nicht veröffentlicht. https://github.com/aspnet/EntityFramework/issues/3545 – Tseng

2

ApplicationUser erbt von IdentityUser Basisklasse, die als mit einer Zeichenkette als ID definiert ist. Um also wirklich eine GUID/uniqueidentifier zu verwenden, müssen Sie nicht von dieser Basisklasse erben.

Beachten Sie, dass intern Guid-Zeichenfolgen für IDs verwendet werden. Sie sollten zumindest die Lage sein, die Feldgröße des Schlüssels zu begrenzen, wie hier gezeigt:

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

     }); 

    } 
} 

Es ist möglich, Guids/unique für den Schlüssel zu verwenden, aber das wird mehr Arbeit erfordern, zusätzlich zu Ihrer eigenen Base Klasse (oder verwenden Sie überhaupt keine Basisklasse) und verwenden Sie einen benutzerdefinierten DbContext, um das Modell zuzuordnen. Kreditaufnahme und die EF code from here modifizieren sollten Sie gehen, würden Sie die virtuellen Methoden von UserStore und außer Kraft zum Nachschlagen eines Benutzers von id erben müssen, da die Schnittstelle IUserStore die Methodensignatur mit einem String FindById definiert. Wenn Sie also überschreiben, müssen Sie die Zeichenfolge in eine Methode umwandeln, in der Methoden, die Sie nach ID abrufen oder suchen müssen.

mir genau das in meinem cloudscribe project zu tun, das eine benutzerdefinierten Multi-Tenant-Implementierung von Identitäts

EDIT hat: eigentlich näheres Hinsehen auf dem Code des IdentityUser eine generische Version, wo Sie den Typen des Schlüssels definieren

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

So können Sie möglicherweise nur Ihre eigene Basisklasse definieren wie

IdentityUser<Guid> 

aber ich denke immer noch, Sie müssten die UserStore-Methoden überschreiben, die eine ID-Zeichenfolge annehmen und die Zeichenfolge in eine GUID konvertieren.

9

Ich habe die Migrationen für dieses Beispiel noch nicht durcheinandergebracht (sie könnten einige Verbesserungen benötigen), jedoch ist ASP.NET Identity v3 weitaus erweiterbarer als v2 in dieser Hinsicht.

Im Folgenden sollen Ihnen einen Identitätsspeicher geben, basierend auf Guid Primärschlüssel für Benutzer und Rollen gleichermaßen:

public class ApplicationUser : IdentityUser<Guid> 
{ 
} 

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

und in Ihrer Startklasse:

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

Ebenso, wenn Sie nicht tun Wenn Sie dem Identitätsbenutzer benutzerdefinierte Felder hinzufügen oder Ihre Optionen anpassen möchten, können Sie einfach Folgendes tun:

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

und in Ihrem Start:

services 
    .AddIdentity<IdentityUser<Guid>, IdentityRole<Guid>>() 
    .AddEntityFrameworkStores<GuidDataContext, Guid>() 
    .AddDefaultTokenProviders(); 
Verwandte Themen