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

.NET 6 Identity添加迁移时int外键与主键类型不兼容报错

问题根源

报错核心原因是Klienti实体继承了ASP.NET Core Identity默认的IdentityUser基类,该基类自带类型为string的主键属性Id。你虽然在Klienti中定义了int类型的KlientiId,但既没有显式配置该属性为主键,也没有修改Identity默认的主键类型规则,EF Core在配置关系时会自动将基类的string类型Id识别为Klienti的主键,和MyCart中int类型的外键KlientiId类型不匹配,最终触发报错。

修复方案

二选一即可:

  • 方案1:沿用Identity默认的string类型主键
    直接将MyCart实体中的外键属性类型修改为和主键一致:

    public partial class MyCart
    {
        public int CartItemId { get; set; }
        // 外键类型从int改为string
        public string KlientiId { get; set; }
        public int FoodId { get; set; }
    
        public virtual Food Food { get; set; } = null!;
        public virtual Klienti Klienti { get; set; } = null!;
    }
    

    修改后重新生成迁移即可,EF Core会自动识别类型匹配的外键关系。

  • 方案2:使用int类型作为用户实体主键(匹配你当前的代码设计)
    按以下步骤修改配置:

    1. 修改Klienti类的继承基类为泛型版本,指定主键类型为int。如果不需要保留自定义的KlientiId属性,可以直接删除该属性,基类会自带int类型的Id属性作为主键:
    // 继承的基类从IdentityUser改为IdentityUser<int>
    public partial class Klienti : IdentityUser<int>
    {
        public Klienti()
        {
            MyCarts = new HashSet<MyCart>();
        }
    
        // 若使用基类自带的int类型Id作为主键,可删除自定义的KlientiId属性
        // public int KlientiId { get; set; }
        public string Name { get; set; } = null!;
        public string Surname { get; set; } = null!;
        public string Email { get; set; } = null!;
        public string Password { get; set; } = null!;
        public string PhoneNumber { get; set; } = null!;
        public string StreetName { get; set; } = null!;
        public string ZipCode { get; set; } = null!;
        public string City { get; set; } = null!;
        public string Role { get; set; } = null!;
    
        public virtual ICollection<MyCart> MyCarts { get; set; }
    }
    
    1. 修改Program.cs(或旧版本的Startup.cs)中的Identity服务注册代码,同步指定主键类型为int:
    // 原写法一般为services.AddDefaultIdentity<Klienti>(...)
    services.AddDefaultIdentity<Klienti>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddRoles<IdentityRole<int>>() // 角色实体主键同步指定为int
        .AddEntityFrameworkStores<你的应用DbContext类型, int>(); // 第二个泛型参数指定主键为int类型
    
    1. 检查Fluent API配置:你当前写的entity.HasOne(d => d.Klienti).WithMany(p => p.MyCarts).HasForeignKey(d => d.KlientiId)逻辑不需要改动,如果之前删除了自定义的KlientiId属性、改用基类的Id作为主键,把外键配置里的d.KlientiId改成d.KlientiId(对应外键列名)或者调整属性名和主键对齐即可。
    2. 如果之前已经生成过迁移或创建过数据库,先删除旧的迁移文件、清理数据库中已有的Identity相关表,再重新执行Add-Migration生成新的迁移文件即可。

补充说明:如果坚持要保留自定义的KlientiId属性作为主键、不使用Identity基类提供的Id属性,只需要在modelBuilder.Entity<Klienti>的配置块中显式加一行entity.HasKey(e => e.KlientiId);,同时把Klienti的继承改成IdentityUser<int>即可,但这种写法不符合Identity的默认约定,后续维护成本更高,不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:18:19