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

.NET Core 2.0认证中如何将用户表主键列Id改为UserId

解决.NET Core 2.0 Identity用户主键列名从Id改为UserId的SqlException问题

嘿,我之前在.NET Core 2.0里折腾Identity的时候也碰到过一模一样的问题!你已经改了数据库列和自定义IdentityUser类,但其实还漏掉了几个关键的EF Core映射配置,导致框架还是在找默认的Id列。下面是完整的解决步骤:

1. 确认自定义IdentityUser类的正确配置

首先,你的自定义用户类需要显式重写Id属性,并指定列名(数据注解或Fluent API都可以,推荐后者更灵活)。示例代码:

public class AppUser : IdentityUser<int>
{
    // 用数据注解指定列名
    [Column("UserId")]
    public override int Id { get; set; }

    // 你的其他自定义属性...
}

2. 在DbContext中显式配置所有Identity关联表的映射

这是最关键的一步!Identity框架除了用户表,还有用户声明、用户角色、用户登录、用户令牌这些关联表,它们默认都会关联用户表的Id列。你需要在OnModelCreating方法里修改这些表的外键映射,让它们指向新的UserId列:

public class ApplicationDbContext : IdentityDbContext<AppUser, IdentityRole<int>, int>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // 配置用户表的主键列名
        modelBuilder.Entity<AppUser>(entity =>
        {
            entity.HasKey(u => u.Id);
            entity.Property(u => u.Id).HasColumnName("UserId");
        });

        // 配置用户声明表的外键关联到UserId
        modelBuilder.Entity<IdentityUserClaim<int>>(entity =>
        {
            entity.HasOne<AppUser>()
                  .WithMany()
                  .HasForeignKey(uc => uc.UserId)
                  .HasPrincipalKey(u => u.Id); // 关联到AppUser的Id(即UserId列)
            entity.Property(uc => uc.UserId).HasColumnName("UserId");
        });

        // 配置用户角色关联表
        modelBuilder.Entity<IdentityUserRole<int>>(entity =>
        {
            entity.HasOne<AppUser>()
                  .WithMany()
                  .HasForeignKey(ur => ur.UserId)
                  .HasPrincipalKey(u => u.Id);
            entity.Property(ur => ur.UserId).HasColumnName("UserId");
        });

        // 配置用户登录表
        modelBuilder.Entity<IdentityUserLogin<int>>(entity =>
        {
            entity.HasOne<AppUser>()
                  .WithMany()
                  .HasForeignKey(ul => ul.UserId)
                  .HasPrincipalKey(u => u.Id);
            entity.Property(ul => ul.UserId).HasColumnName("UserId");
        });

        // 配置用户令牌表
        modelBuilder.Entity<IdentityUserToken<int>>(entity =>
        {
            entity.HasOne<AppUser>()
                  .WithMany()
                  .HasForeignKey(ut => ut.UserId)
                  .HasPrincipalKey(u => u.Id);
            entity.Property(ut => ut.UserId).HasColumnName("UserId");
        });
    }
}

3. 确保Startup.cs中使用自定义用户类配置Identity

在ConfigureServices里,要明确指定你的自定义用户类和角色类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    // 使用自定义的AppUser类,主键类型为int
    services.AddIdentity<AppUser, IdentityRole<int>>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    // 其他服务配置...
}

4. 生成迁移并更新数据库

最后,运行以下命令更新数据库结构,确保所有映射都生效:

# 生成新的迁移脚本
Add-Migration UpdateUserIdColumnNames

# 应用迁移到数据库
Update-Database

这样操作之后,EF Core就会正确使用UserId作为用户表的主键列,并且所有关联表的外键也会指向这个列,不会再出现Invalid column name 'Id'的错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:49:25