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

ASP.NET Core 5执行Add-Migration时User实体无主键错误如何解决

问题:执行Add-Migration Category命令时主键识别错误

在ASP.NET Core 5中执行Add-Migration Category命令时,出现如下错误:

实体类型‘User’需要定义主键。如果您打算使用无键实体类型,请在‘OnModelCreating’中调用‘HasNoKey’。

尽管已在User实体中定义主键字段,错误依然存在。以下是相关代码:

User实体

namespace UCI.Domain.Entities.Users
{
    public class User: BaseEntity
    {
        public long id { get; set; }
        public string FullName { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public bool IsActive { get; set; }
        
        public ICollection<UserInRole> userInRoles { get; set; }
    }
}

Role实体

namespace UCI.Domain.Entities.Users
{
    public class Role
    {
        public long id { get; set; }
        public string name { get; set; }
        public ICollection<UserInRole> UserInRoles { get; set; }
    }
}

UserInRole实体

namespace UCI.Domain.Entities.Users
{
    public class UserInRole
    {
        public long id { get; set; }

        // 关联表的外键定义
        public virtual User User { get; set; }
        public long UserId { get; set; }

        // 关联表的外键定义
        public virtual Role Role { get; set; }
        public long RoleId { get; set; }
    }
}

数据库上下文

namespace UCI.Persistence.Context
{
    public class DataBaseContext : DbContext,IDataBaseContext
    {
        public DataBaseContext(DbContextOptions options):base (options)
        {
        }

        public DbSet<User> Users { get; set; }
        public DbSet<Role> Roles { get; set; }
        public DbSet<UserInRole> userInRoles { get; set; }
        public DbSet<Category> Category { get; set; }
  
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().HasIndex(u => u.Email).IsUnique();

            // modelBuilder.Entity<User>().HasQueryFilter(p => !p.IsRemoved);
            // modelBuilder.Entity<Role>().HasQueryFilter(p => !p.IsRemoved);
            // modelBuilder.Entity<UserInRole>().HasQueryFilter(p => !p.IsRemoved);
            // modelBuilder.Entity<Category>().HasQueryFilter(p => !p.IsRemoved);

            modelBuilder.Entity<Role>().HasData(new Role { id = 1, name = nameof(UserRole.Admin) });
            modelBuilder.Entity<Role>().HasData(new Role { id = 2,  name = nameof(UserRole.Oprator) }); 
            modelBuilder.Entity<Role>().HasData(new Role { id = 3, name = nameof(UserRole.Customer) });
        }
    }
}

解决方案

错误根源是EF Core的主键自动识别规则:默认仅会识别首字母大写的Id(或[实体名]Id)作为主键,而你的实体中主键字段是小写的id,导致EF无法自动识别。

可通过以下三种方式解决:

1. 修改属性名符合约定

将User、Role、UserInRole实体中的id字段改为首字母大写的Id:

public long Id { get; set; }

这是最贴合EF Core设计规范的方案,后续无需额外配置。

2. 手动配置主键(Fluent API)

在DataBaseContext的OnModelCreating方法中,为每个实体显式指定主键:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 新增主键配置
    modelBuilder.Entity<User>().HasKey(u => u.id);
    modelBuilder.Entity<Role>().HasKey(r => r.id);
    modelBuilder.Entity<UserInRole>().HasKey(ur => ur.id);

    // 原有代码
    modelBuilder.Entity<User>().HasIndex(u => u.Email).IsUnique();
    // ...其他种子数据配置
}

3. 使用DataAnnotations特性标记主键

在每个实体的id字段上添加[Key]特性:

using System.ComponentModel.DataAnnotations;

public class User: BaseEntity
{
    [Key]
    public long id { get; set; }
    // ...其他属性
}

Role和UserInRole实体需做相同修改。

任意选择一种方式修改后,重新执行Add-Migration Category命令即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:35:41