EF Core插入含嵌套子实体的ProjectRequest时Translation的ProjectRequestId为0的原因
EF Core 嵌套实体插入时Translation的ProjectRequestId未自动赋值问题
实体定义
public class Entity { public int Id { get; set; } public DateTime CreatedOn { get; set; } public DateTime? ModifiedOn { get; set; } } public class EntityBase : Entity { [ForeignKey("CreatedBy")] public int CreatedById { get; set; } public User CreatedBy { get; set; } [ForeignKey("ModifiedBy")] public int? ModifiedById { get; set; } public User ModifiedBy { get; set; } } public class ProjectRequest : EntityBase { public string RequestTitle { get; set; } public string RequestType { get; set; } ... public virtual ICollection<Material> Materials { get; set; } public virtual ICollection<Translation> Translations { get; set; } } public class Material : EntityBase { [ForeignKey("ProjectRequest")] public int ProjectRequestId { get; set; } public virtual ProjectRequest ProjectRequest { get; set; } ... public virtual ICollection<Translation> Translations { get; set; } } public class Translation:EntityBase { [ForeignKey("ProjectRequest")] public int ProjectRequestId { get; set; } public virtual ProjectRequest ProjectRequest { get; set; } [ForeignKey("Material")] public int MaterialId { get; set; } public virtual Material Material { get; set; } public string ProductMasterText { get; set; } [MaxLength(40)] public string ShortDescription { get; set; } public string MasterDescriptionLine1 { get; set; } public string MasterDescriptionLine2 { get; set; } public string MasterDescriptionLine3 { get; set; } public string LanguageCode { get; set; } }
问题现象
未通过Fluent API修改实体配置,插入包含嵌套Materials和Translations子实体的ProjectRequest对象时,Translation的ProjectRequestId被设置为0,但MaterialId能正确赋值。
原因分析
- EF的自动外键赋值仅针对直接父级导航属性:
Translation是通过Material.Translations集合添加的,属于Material的子实体,EF只会自动识别并填充MaterialId(直接关联的外键)。 Translation的ProjectRequestId是非可空int类型,默认值为0,由于没有显式设置Translation.ProjectRequest导航属性,EF不会自动向上追溯关联ProjectRequest,因此该字段保留默认值0。
解决方案
- 显式设置导航属性:在将
Translation添加到Material.Translations时,同时设置translation.ProjectRequest = projectRequestInstance,EF会自动填充ProjectRequestId。 - 手动赋值外键:直接给
translation.ProjectRequestId赋值为对应的ProjectRequest的Id(如果是新增的ProjectRequest,可利用EF的追踪特性,保存时自动关联,无需提前获取Id)。 - 可选调整字段可空性:如果业务允许,可将
Translation.ProjectRequestId改为int?,避免默认值0的干扰,但建议优先通过导航属性关联的方式解决。
内容的提问来源于stack exchange,提问作者Shashank
相关产品推荐
相关产品推荐

