EF中类与继承类外键关联配置报错,求解决方案
解决方案
问题根源分析
- 第一个错误:
Address是具体类,EF将其视为实体类型,但未定义主键,导致模型验证失败。 - 第二个错误:将
City_ID设为Address的主键,意味着一个City只能对应一个Address,但City中配置的是ICollection<Address>(一对多关系),两者多重性冲突。
具体解决步骤
1. 将Address改为抽象类
因为Address是基类,实际使用的是其子类School,不需要直接实例化Address,将其设为抽象类后,EF不会将它当作独立实体,也就不会要求它必须有主键:
public abstract class Address { public byte Address_Region { get; set; } public string Address_PostalCode { get; set; } public string Address_Line { get; set; } public int City_ID { get; set; } public virtual City City { get; set; } }
2. 配置School的主键及关联关系
创建SchoolConfig类,为School配置主键,并维护与City的一对多关系:
public class SchoolConfig : EntityTypeConfiguration<School> { public SchoolConfig() { // 设置School的主键 HasKey(s => s.School_ID); Property(s => s.School_ID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // 自增主键 // 配置School_Name的长度限制 Property(s => s.School_Name) .HasMaxLength(50) .IsRequired(); // 配置与City的关联:School依赖City,一个City对应多个School HasRequired(s => s.City) .WithMany(c => c.Addresses) .HasForeignKey(s => s.City_ID); } }
3. 保持CityConfig不变
原有的CityConfig配置是正确的,无需修改:
public class CityConfig : EntityTypeConfiguration<City> { public CityConfig() { HasKey(c => c.City_ID); Property(c => c.City_ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); Property(c => c.City_Name).HasMaxLength(30); HasMany(c => c.Addresses).WithRequired(a => a.City).HasForeignKey(a => a.City_ID); } }
4. 确保DBModelContext配置正确
上下文配置已经添加了CityConfig和SchoolConfig,无需额外修改:
public class DBModelContext : DbContext { public virtual DbSet<School> Schools { get; set; } public virtual DbSet<City> Cities { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new CityConfig()); modelBuilder.Configurations.Add(new SchoolConfig()); } }
为什么这样能解决问题?
- 将
Address设为抽象类,避免EF将其当作需要主键的实体类型,解决第一个验证错误。 - 为
School设置独立主键School_ID,让City_ID回归为外键角色,此时City与School(继承自Address)的一对多关系匹配,解决多重性冲突的错误。
内容的提问来源于stack exchange,提问作者Tensy
相关产品推荐
相关产品推荐

