EF Core 5一对一关系插入实体报ItemID列重复指定错误
问题根因
第一个SQL报错是关系配置冲突导致的:你同时使用数据注解特性和Fluent API配置一对一关系,两边的外键定义完全矛盾:
- 实体类上的
[ForeignKey("ItemId")]特性标记Product表的ItemId字段为外键 - Fluent API又标记
MoreProductInfo表的ItemID字段为外键
EF Core根据冲突配置生成INSERT语句时,会给ItemID列重复赋值,直接触发SQL Server的列重复定义错误。
第二次调整后的配置报错是因为一对一关系只能存在一个依赖端(即外键只能归属于其中一张表),你同时给两个实体都配置外键、主参考键,反复切换关系的主从端,违反EF Core的关系配置规则。
另外你在Product构造函数中直接初始化MoreProductInfo并反向绑定导航属性,也会干扰EF Core的对象追踪逻辑,放大字段重复赋值的问题。
修复方案
按以下步骤调整即可:
- 清理实体类上的冲突配置,移除所有和外键相关的数据注解特性,同时删除构造函数中对关联实体的初始化逻辑,修正后的实体代码:
using System.ComponentModel.DataAnnotations; public class Product { [Key] public int ItemId { get; set; } public virtual MoreProductInfo MaterialProperties { get; set; } } public class MoreProductInfo : IObjectSpaceLink, IElipseLookUp { [Key] public int ItemID { get; set; } public virtual Product Product { get; set; } }
- 统一用Fluent API配置共享主键的一对一关系,明确指定主端和依赖端,不要重复配置外键/主参考键:
modelBuilder.Entity<Product>() .HasOne(p => p.MaterialProperties) .WithOne(mpi => mpi.Product) // 指定MoreProductInfo为依赖端,其ItemID字段同时作为主键和外键 .HasForeignKey<MoreProductInfo>(mpi => mpi.ItemID) // 指定Product为主端,关联主参考键为Product的ItemId .HasPrincipalKey<Product>(p => p.ItemId);
- 调整新增实体的代码逻辑,不要依赖构造函数自动创建关联对象,手动保证主外键值一致后再赋值导航属性:
// 新增实体示例 var product = new Product { ItemId = 1001 // 其他Product属性赋值 }; var productInfo = new MoreProductInfo { ItemID = product.ItemId, // 外键值和主表主键保持一致 Product = product // 其他MoreProductInfo属性赋值 }; product.MaterialProperties = productInfo; context.Products.Add(product); context.SaveChanges();
内容的提问来源于stack exchange,提问作者Kirsten
相关产品推荐
相关产品推荐

