You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IdentityUser种子数据报错:已设置Id仍提示未提供必填属性

问题:数据迁移初始化Identity用户时提示“未提供必填属性Id”的解决方案

问题描述

我尝试通过数据迁移初始化2个默认用户(管理员和普通用户),使用IdentityUserConfiguration配置代码。此前已用相同方式成功创建角色,但手动生成迁移时出现错误:无法添加IdentityUser类型的种子实体,未提供必填属性Id。但代码中已明确为Id赋值,请问问题出在哪里?

原配置代码

internal sealed class IdentityUserConfiguration : IEntityTypeConfiguration<IdentityUser>
{
    public void Configure(EntityTypeBuilder<IdentityUser> builder)
    {
        Guid ADMIN_ID = new Guid("0007a13c-6a71-4c93-a7b9-35ea2ba6555e");
        Guid ADMIN_ROLE_ID = new Guid("2c5e174e-3b0e-446f-86af-483d56fd7210");
        Guid USER_ID = new Guid("8e445865-a24d-4543-a6c6-9443d048cdb9");
        Guid USER_ROLE_ID = new Guid("a6c43c31-811b-4c76-82a3-a65fd06078cd");


        //a hasher to hash the password before seeding the user to the db
        var hasherUser = new PasswordHasher<IdentityUser>();
        var hasherAdmin = new PasswordHasher<IdentityUser>();


        //Seeding the User to AspNetUsers table
        //admin
        builder.HasData(
            new IdentityUser
            {
                Id = ADMIN_ID.ToString(), // primary key
                ConcurrencyStamp = ADMIN_ROLE_ID.ToString(),
                UserName = "test@.com",
                NormalizedUserName = "TEST@TEST.COM",
                PasswordHash = hasherAdmin.HashPassword(null, "Pa$$w0rd")

            }
        );


        //Seeding the relation between our user and role to AspNetUserRoles table
        builder.HasData(
            new IdentityUserRole<string>
            {
                RoleId = ADMIN_ROLE_ID.ToString(),
                UserId = ADMIN_ID.ToString()
            }
        );


        //Seeding the User to AspNetUsers table
        //standard user
        builder.HasData(
            new IdentityUser
            {
                Id = USER_ID.ToString(), // primary key
                ConcurrencyStamp = USER_ROLE_ID.ToString(),
                UserName = "user@user.com",
                NormalizedUserName = "USER@USER.COM",
                PasswordHash = hasherUser.HashPassword(null, "Pa$$w0rd")
            }
        );


        //Seeding the relation between our user and role to AspNetUserRoles table
        builder.HasData(
            new IdentityUserRole<string>
            {
                RoleId = USER_ROLE_ID.ToString(),
                UserId = USER_ID.ToString()
            }
        );


    }
}

问题原因

  • 跨实体配置种子数据:你在IdentityUser对应的配置类中,调用builder.HasData添加了IdentityUserRole<string>类型的实体。EF Core会认为这些种子数据属于当前配置的IdentityUser类型,而IdentityUserRole没有Id属性,因此抛出“未提供必填属性Id”的错误。
  • 重复调用HasData本身没问题,但混淆不同实体类型的种子数据是核心问题。

解决方法

1. 拆分配置类,单独管理用户角色关联数据

创建专门的IdentityUserRoleConfiguration类,负责配置AspNetUserRoles表的种子数据:

internal sealed class IdentityUserRoleConfiguration : IEntityTypeConfiguration<IdentityUserRole<string>>
{
    public void Configure(EntityTypeBuilder<IdentityUserRole<string>> builder)
    {
        Guid ADMIN_ID = new Guid("0007a13c-6a71-4c93-a7b9-35ea2ba6555e");
        Guid ADMIN_ROLE_ID = new Guid("2c5e174e-3b0e-446f-86af-483d56fd7210");
        Guid USER_ID = new Guid("8e445865-a24d-4543-a6c6-9443d048cdb9");
        Guid USER_ROLE_ID = new Guid("a6c43c31-811b-4c76-82a3-a65fd06078cd");

        builder.HasData(
            new IdentityUserRole<string>
            {
                RoleId = ADMIN_ROLE_ID.ToString(),
                UserId = ADMIN_ID.ToString()
            },
            new IdentityUserRole<string>
            {
                RoleId = USER_ROLE_ID.ToString(),
                UserId = USER_ID.ToString()
            }
        );
    }
}

2. 修正原IdentityUserConfiguration,仅保留用户数据

移除所有IdentityUserRole相关的HasData调用,只保留IdentityUser类型的种子数据,同时修正两处不合理的细节:

internal sealed class IdentityUserConfiguration : IEntityTypeConfiguration<IdentityUser>
{
    public void Configure(EntityTypeBuilder<IdentityUser> builder)
    {
        Guid ADMIN_ID = new Guid("0007a13c-6a71-4c93-a7b9-35ea2ba6555e");
        Guid USER_ID = new Guid("8e445865-a24d-4543-a6c6-9443d048cdb9");

        // 单个PasswordHasher即可复用
        var hasher = new PasswordHasher<IdentityUser>();

        builder.HasData(
            // 管理员用户
            new IdentityUser
            {
                Id = ADMIN_ID.ToString(),
                ConcurrencyStamp = ADMIN_ID.ToString(), // 改用用户自身Guid,保证唯一性
                UserName = "test@test.com", // 修正无效邮箱格式
                NormalizedUserName = "TEST@TEST.COM",
                PasswordHash = hasher.HashPassword(null, "Pa$$w0rd")
            },
            // 普通用户
            new IdentityUser
            {
                Id = USER_ID.ToString(),
                ConcurrencyStamp = USER_ID.ToString(),
                UserName = "user@user.com",
                NormalizedUserName = "USER@USER.COM",
                PasswordHash = hasher.HashPassword(null, "Pa$$w0rd")
            }
        );
    }
}

3. 在DbContext中注册所有配置类

确保OnModelCreating方法中同时注册这两个配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfiguration(new IdentityUserConfiguration());
    modelBuilder.ApplyConfiguration(new IdentityUserRoleConfiguration());
    // 其他Identity相关配置(如角色)...
}

4. 重新生成迁移

执行以下命令重新生成迁移并更新数据库:

Add-Migration SeedUsersAndRoles
Update-Database

内容的提问来源于stack exchange,提问作者misuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:32:10