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

EF Core配置单个导航属性报错:违反唯一约束IX_ItemDB_CategoryID

问题:EF Core配置单导航属性时出现唯一键约束错误

我正在开发一个基于EF Core的项目,希望通过单个导航属性使用Category的外键,让Item存储Category的外键并能显示分类名称。

实体类定义

[Table("Item" , Schema = "public")]
public class Item
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ItemID {get; set;}
    public string Name {get; set;}
    public int CategoryID {get; set;}
    //Single Navigation Property
    public Category Category {get; set;}
}

[Table("Category" , Schema = "public")]
public class Category
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CategoryID {get; set;}
    public string Name {get; set;}
}

DbContext配置代码

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Item>().ToTable("Item");
    modelBuilder.Entity<Category>().ToTable("Category");
    
    modelBuilder.Entity<Item>()
                .HasOne(i=>i.Category)
                .WithOne()
                .HasForeignKey<Item>(i=>i.CategoryID);
}

运行时错误

Duplicate key value violates unique constraint "IX_ItemDB_CategoryID"

显然这意味着Item中的CategoryID不能重复,请问我哪里配置错误了?


问题原因与解决方法

原因

你用.WithOne()配置关联关系时,EF Core会默认识别为一对一关系:即一个Item对应一个Category,同时一个Category也只能对应一个Item。为了保证这个约束,EF Core会自动给Item表的CategoryID字段添加唯一索引,所以当你尝试给多个Item设置同一个CategoryID时就会触发唯一键冲突错误。

但你的实际需求应该是一对多关系:一个Category可以被多个Item关联,一个Item只属于一个Category。

解决方法

把配置中的.WithOne()改成.WithMany()即可,无需在Category类中定义反向导航属性(满足你单导航属性的需求),EF Core会自动识别这是一对多关系,不会给CategoryID添加唯一约束。

修改后的DbContext配置代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Item>().ToTable("Item");
    modelBuilder.Entity<Category>().ToTable("Category");
    
    modelBuilder.Entity<Item>()
                .HasOne(i => i.Category)
                .WithMany() // 修改为WithMany,无需指定反向导航
                .HasForeignKey(i => i.CategoryID);
}

如果后续需要在Category类中添加反向导航属性(比如public ICollection<Item> Items { get; set; }),只需把.WithMany()改成.WithMany(c => c.Items)即可,当前的配置已经能满足你单导航属性的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:50:29