Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make EF-Core use a Guid instead of String for its ID/Primary key

When I look at the ASP.NET 3 Identity it uses a string and not a Guid for the unique primary key.

In my Entity Framework code first Users' ApplicationUser class I inherit the Identity class

public class ApplicationUser : IdentityUser { } 

which results in when I create my Entity Framework migrations a table aspnetusers getting created with a key type ofnvarchar(450) instead of uniqueidentifier

When I compare this to ASP.NET Identity 2 ENtity Framework project it created an ID field of uniqueidentifier and not nvarchar(450)

I would imagine for database performance primary keys and foreign keys of uniqueidentifier would be better than nvarchar(450)

Is there a way to use for the unique key Guid instead of string and uniqueidentifier instead of nvarchar(450) with ASP.NET Identity 3?

There is a previous question how to convert a String to a Guid but I want the database table Id to be a Guid.

I found another question as well for a previous BETA when the length was nvarchar(128). The reason given is that not all databases support Guids and it was changed for flexibility.

Is there must be an easy way to change from string to Guid without rewriting the whole identity 3?

nvarchar(450) is really overkill and gives all kinds of warnings when creating SQL Server database constraints. Database admins will definitively not like these warnings.

like image 788
devfric Avatar asked May 11 '16 14:05

devfric


People also ask

What is the EF core convention for primary keys?

EF Core will specify that the primary key column values are generated automatically by the database.

How do you create a composite primary key in EF core?

Entity Framework Core supports composite keys - primary key values generated from two or more fields in the database. Composite keys are not covered by conventions or data annotation attributes. The only way to configure composite keys is to use the HasKey method.

How do you configure a primary key for an entity in Entity Framework fluent API?

Configuring a primary key By convention, a property named Id or <type name>Id will be configured as the primary key of an entity. Owned entity types use different rules to define keys. You can configure a single property to be the primary key of an entity as follows: Data Annotations.


2 Answers

You need custom ApplicationUser inherit from IdentityUser<TKey> and custom Role inherit from IdentityRole<TKey>

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

Custom context class inherit from IdentityDbContext<ApplicationUser, Role, TKey> and use fluent api for auto generate guid keys.

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

then in Startup add Identity service to container like this

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

If you have not created the database, clear the migrations folder and run ef commands

like image 82
tmg Avatar answered Sep 18 '22 13:09

tmg


I haven't messed with the migrations for this example yet (they might need some tweaks), however ASP.NET Identity v3 is far more extensible than v2 was in this regard.

The following should give you an Identity store based on Guid primary keys for Users and Roles alike:

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

and in your startup class:

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

Likewise, if you didn't need to add any custom fields to the Identity User, or customize your options, you could just do the following:

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

and in your startup:

services     .AddIdentity<IdentityUser<Guid>, IdentityRole<Guid>>()     .AddEntityFrameworkStores<GuidDataContext, Guid>()     .AddDefaultTokenProviders(); 
like image 26
Ron DeFreitas Avatar answered Sep 20 '22 13:09

Ron DeFreitas