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

asp.net-core asp.net-identity asp.net-identity-3 c# entity-framework-core

Question

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.

1
28
9/9/2019 1:27:11 PM

Accepted Answer

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

48
5/18/2016 9:19:49 PM

Popular Answer

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow