在 EF Core 8 中,为什么即使我显式配置外键,迁移后表中仍然会生成影子外键?

问题描述 投票:0回答:1

我有一个主要实体类

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 使用我显式定义的外键来描述它们之间的一对多关系。即使查阅了官方文档,我仍然无法理解为什么会发生这种情况。这让我很困惑。预先感谢。

c# .net entity-framework entity-framework-core
1个回答
0
投票

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 是否存在反向关系以及预期存在什么反向关系。剩下的任何事情都会尝试自行解决。

© www.soinside.com 2019 - 2024. All rights reserved.