我有一个主要实体类
PurchasePlanEntity
和一个详细实体类PurchasePlanDetailEntity
,它们具有一对多关系。我在 DbContext 类中显式定义了外键,但是使用迁移后,表中仍然生成了两个影子外键 PurchasePlanEntityOrgId
和 PurchasePlanEntityPurcPlanId
。此外,还创建了两个外键约束 FK_purchasePlanDetailEntity_purchasePlan_PurchasePlanEntityPurcPlanId_PurchasePlanEntityOrgId
和 FK_purchasePlanDetailEntity_purchasePlan_purcPlanId_orgId
。即使我已经明确配置了外键,为什么会发生这种情况?
// main entity class.
[Table("purchasePlan")]
public class PurchasePlanEntity
{
[Column("purcPlanId")]
public string? PurcPlanId { get; set; }
[Column("orgId")]
public string? OrgId { get; set; }
public List<PurchasePlanDetailEntity> DetailList { get; } = new();
}
// detail entity class.
[Table("purchasePlanDetailEntity")]
public class PurchasePlanDetailEntity
{
[Column("purcPlanDetlId")]
public string? PurcPlanDetlId { get; set; }
#region foreign-key
[Column("purcPlanId")]
public string? PurcPlanId { get; set; }
[Column("orgId")]
public string? OrgId { get; set; }
#endregion
public PurchasePlanEntity PurchasePlanEntity { get; set; } = null!;
}
// explicit foreign key configuration.
modelBuilder.Entity<PurchasePlanEntity>()
.HasMany<PurchasePlanDetailEntity>()
.WithOne()
.HasForeignKey(e => new { e.PurcPlanId, e.OrgId });
// explicit primary key configuration.
modelBuilder.Entity<PurchasePlanDetailEntity>()
.HasKey(e => new { e.PurcPlanId, e.OrgId, e.PurcPlanDetlId });
我期望 EF Core 使用我显式定义的外键来描述它们之间的一对多关系。即使查阅了官方文档,我仍然无法理解为什么会发生这种情况。这让我很困惑。预先感谢。
EF 可能会感到困惑,因为您没有链接定向引用。尝试:
modelBuilder.Entity<PurchasePlanEntity>()
.HasMany<PurchasePlanDetailEntity>()
.WithOne(e => e.PurchasePlanEntity)
.HasForeignKey(e => new { e.PurcPlanId, e.OrgId });
因为您的PurchasePlanDetailEntity有一个PurchasePlanEntity引用。否则,当 EF 遇到此问题并被明确告知关系的现有多方没有双向引用时,它将希望使用不同的 FK 来设置新的引用。
您拥有单独的可选参考的情况的常见示例如下:
public class User
{
[Key]
public int UserId { get; protected set; }
public virtual ICollection<Order> Orders { get; protected set;} = new List<Order>();
}
public class Order
{
[Key]
public int OrderId { get; protected set; }
public virtual User CreatedBy { get; protected set; }
public virtual User ModifiedBy { get; protected set; }
}
这里User.Orders的关系我们可能不想要双向引用,所以我们配置:
.HasMany(e => e.Orders)
.WithOne()
.UseForeignKey("UserId");
或者它可以有一个“User”属性来返回该订单所属的用户,或者如果用户只能为自己创建订单而不能为其他用户创建订单,则可以使用“CreatedBy”。这仍然会让 EF 来解决“ModifiedBy”问题。在任何一种情况下,都需要明确告知 EF 是否存在反向关系以及预期存在什么反向关系。剩下的任何事情都会尝试自行解决。