如何使EF-Core为其ID /主键使用Guid而不是String

dev*_*ric 21 c# asp.net-identity entity-framework-core asp.net-identity-3 asp.net-core

当我查看ASP.NET 3 Identity时,它使用a string而不是a Guid用于唯一主键.

在我的Entity Framework code first用户ApplicationUser类中,我继承了Identity类

public class ApplicationUser : IdentityUser
{
}
Run Code Online (Sandbox Code Playgroud)

这导致在我创建实体框架迁移时aspnetusers,使用密钥类型nvarchar(450)而不是创建的表创建uniqueidentifier

当我将它与ASP.NET Identity 2 ENtity Framework项目进行比较时,它创建了一个ID字段uniqueidentifier而不是nvarchar(450)

我会想象对于数据库性能主键和外键uniqueidentifier会更好nvarchar(450)

有没有办法用于唯一键Guid而不是用stringuniqueidentifier不是nvarchar(450)ASP.NET Identity 3

先前有一个问题如何将String转换为Guid,但我希望数据库表Id是Guid.

当长度为nvarchar(128)时,我发现了以前的BETA的另一个问题.给出的理由是并非所有数据库都支持Guids,并且它的灵活性也发生了变化.

是否必须有一种简单的方法从字符串更改为Guid而不重写整体identity 3

nvarchar(450)在创建SQL Server数据库约束时,实际上是过度杀伤并提供各种警告.数据库管理员肯定不会喜欢这些警告.

tmg*_*tmg 43

您需要自定义ApplicationUser继承IdentityUser<TKey>和自定义角色继承自IdentityRole<TKey>

public class ApplicationUser : IdentityUser<Guid> { }    
public class Role : IdentityRole<Guid> { }
Run Code Online (Sandbox Code Playgroud)

自定义上下文类继承IdentityDbContext<ApplicationUser, Role, TKey>并使用流畅的api来自动生成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()");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在Startup中将Identity Service添加到容器中

services.AddIdentity<ApplicationUser, Role>()
        .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
        .AddDefaultTokenProviders()
        .AddUserStore<UserStore<ApplicationUser, Role, ApplicationDbContext, Guid>> ()
        .AddRoleStore<RoleStore<Role, ApplicationDbContext, Guid>>();
Run Code Online (Sandbox Code Playgroud)

如果尚未创建数据库,请清除迁移文件夹并运行ef命令

  • 这不适用于 ASP.Net Core 3.1 - AddEntityFrameworkStores 没有描述 2 个通用参数的方法,第二个是类型 - 我们如何使用 ASP.Net Core 3.1 做到这一点? (3认同)

Ron*_*tas 9

我还没有搞过这个例子的迁移(他们可能需要一些调整),但是ASP.NET Identity v3在这方面比v2更具可扩展性.

以下内容应该为您提供基于用户和角色的Guid主键的Identity存储:

public class ApplicationUser : IdentityUser<Guid>
{
}

public class GuidDataContext :
    IdentityDbContext<ApplicationUser, IdentityRole<Guid>, Guid>
{
}
Run Code Online (Sandbox Code Playgroud)

在你的启动课上:

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

同样,如果您不需要向身份用户添加任何自定义字段,或自定义您的选项,您可以执行以下操作:

public class GuidDataContext :
    IdentityDbContext<IdentityUser<Guid>, IdentityRole<Guid>, Guid>
{ 
}
Run Code Online (Sandbox Code Playgroud)

在你的创业公司:

services
    .AddIdentity<IdentityUser<Guid>, IdentityRole<Guid>>()
    .AddEntityFrameworkStores<GuidDataContext, Guid>()
    .AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)