EF7 Code First含关联属性的嵌入类无主键问题求助
解决方案:使用EF Core的拥有实体类型(Owned Entity Types)
你需要把ProcurmentData定义为拥有实体类型,这是EF Core专门为这类「嵌入主实体表、无独立主键、可复用的类型」设计的特性,完全匹配你的需求:无需单独建表、保留类型结构方便扩展、支持导航属性(比如Supplier),还不会和现有继承结构冲突。
步骤1:标记ProcurmentData为拥有实体
有两种实现方式:
方式一:用DataAnnotations特性
直接在ProcurmentData类上添加[Owned]特性:
using System.ComponentModel.DataAnnotations.Schema; [Owned] public class ProcurmentData { public virtual Supplier? Supplier { get; set; } public DateTime? PurchaseDate { get; set; } public DateTime? DeliveryDate { get; set; } public decimal? Cost { get; set; } }
方式二:用Fluent API配置(推荐,更灵活)
如果不想在实体类上加特性,在你的DbContext的OnModelCreating方法里配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置PowerTool的Procurment为拥有实体 modelBuilder.Entity<PowerTool>() .OwnsOne(p => p.Procurment); // 配置Block的Procurment为拥有实体 modelBuilder.Entity<Block>() .OwnsOne(b => b.Procurment); // 保留现有继承结构的配置(比如Tool的鉴别器) modelBuilder.Entity<Tool>() .HasDiscriminator<string>("ToolType") .HasValue<HomemadeTool>("Homemade") .HasValue<PowerTool>("Power"); }
步骤2:验证效果
配置完成后,EF Core会自动:
- 不生成单独的
ProcurmentData表 - 将
ProcurmentData的字段嵌入到主实体表中,列名默认带前缀(比如PowerTool表会生成Procurment_PurchaseDate、Procurment_DeliveryDate、Procurment_Cost) - 自动处理
Supplier关联的外键,生成类似Procurment_SupplierId的列(若Supplier是独立实体)
扩展说明
- 若要自定义嵌入字段的列名,可在Fluent API里细化配置:
modelBuilder.Entity<PowerTool>() .OwnsOne(p => p.Procurment, pd => { pd.Property(x => x.PurchaseDate).HasColumnName("PurchaseDate"); pd.Property(x => x.Cost).HasColumnName("ProcurementCost"); // 自定义Supplier关联的外键列名 pd.HasOne(x => x.Supplier).WithMany().HasForeignKey("SupplierId"); });
- 拥有实体类型支持后续扩展:给
ProcurmentData新增字段时,EF Core会自动在主实体表中添加对应列,无需修改主实体类。
内容的提问来源于stack exchange,提问作者J.Kz
相关产品推荐
相关产品推荐

