EF6 Code-First一对一关系配置无效,求助正确配置方法
EF6 Code-First 一对一关系正确配置指导
问题分析
你当前的配置存在两个核心问题:
- 使用
Map(c => c.MapKey("PriceUnitID"))会让EF在ProductPrice表中生成非主键的外键字段,但实体类未对应该属性,且一对一关系要求外键必须带唯一约束,否则会默认转为一对多。 - 配置逻辑的依赖关系未通过实体结构正确映射,导致EF无法识别预期的一对一关联。
下面给出两种可行的配置方案,可根据业务需求选择:
方案一:共享主键一对一关系(推荐)
这种模式下,ProductPrice的主键同时作为PriceUnit的外键,两个实体共享同一主键值,是EF6原生支持的一对一关系实现方式。
调整实体类
[Table("ProductPrice", Schema = "Product")] public class ProductPrice { // 主键同时作为PriceUnit的外键 [Key, ForeignKey("PriceUnit")] public int ProductPriceID { get; set; } public float MonthlyPrice { get; set; } public float YearlyPrice { get; set; } public virtual PriceUnit PriceUnit { get; set; } } [Table("PriceUnit", Schema = "General")] public class PriceUnit { [Key] public int PriceUnitID { get; set; } public string Name { get; set; } public string ShortName { get; set; } public string Contract { get; set; } public virtual ProductPrice ProductPrice { get; set; } }
DbContext配置
public DbSet<PriceUnit> PriceUnits { get; set; } public DbSet<ProductPrice> ProductPrices { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 配置PriceUnit可选关联ProductPrice,ProductPrice必须关联PriceUnit modelBuilder.Entity<PriceUnit>() .HasOptional(p => p.ProductPrice) .WithRequired(c => c.PriceUnit) .WillCascadeOnDelete(false); }
方案二:独立外键(带唯一约束)的一对一关系
如果需要保留各自独立的主键,可在ProductPrice中添加外键字段并配置唯一约束:
调整实体类
[Table("ProductPrice", Schema = "Product")] public class ProductPrice { [Key] public int ProductPriceID { get; set; } public float MonthlyPrice { get; set; } public float YearlyPrice { get; set; } // 添加外键字段 public int PriceUnitID { get; set; } public virtual PriceUnit PriceUnit { get; set; } } [Table("PriceUnit", Schema = "General")] public class PriceUnit { [Key] public int PriceUnitID { get; set; } public string Name { get; set; } public string ShortName { get; set; } public string Contract { get; set; } public virtual ProductPrice ProductPrice { get; set; } }
DbContext配置
public DbSet<PriceUnit> PriceUnits { get; set; } public DbSet<ProductPrice> ProductPrices { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<ProductPrice>() .HasRequired(c => c.PriceUnit) .WithOptional(p => p.ProductPrice) // 指定外键字段 .HasForeignKey(c => c.PriceUnitID) .WillCascadeOnDelete(false); // 给外键添加唯一约束,确保一对一关联 modelBuilder.Entity<ProductPrice>() .Property(c => c.PriceUnitID) .IsUnique(); }
验证效果
配置完成后可通过以下方式确认:
- 生成数据库后,检查
ProductPrice表:方案一会显示主键关联PriceUnit主键;方案二会显示PriceUnitID字段带唯一约束。 - 编写测试代码,尝试创建多个
ProductPrice关联同一个PriceUnit,若抛出异常则说明一对一关系生效。
内容的提问来源于stack exchange,提问作者Elif şahin
相关产品推荐
相关产品推荐

