【问题标题】:How to configure one-to-many relationship with navigation property only on one side (on collection side) with EF Core 5?如何使用 EF Core 5 仅在一侧(在集合端)配置与导航属性的一对多关系?
【发布时间】:2021-05-30 18:18:12
【问题描述】:

假设我们有 AirportRunway 类: 在两个表之间具有完美的一对多关系:Play 和 Player:

public class Airport
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual IList<Runway> Runways { get; set; }
}

public class Runway
{
    public int Id { get; set; }    
    public string Name { get; set; }
    //public int AirportId { get; set; } <- I don't need it!!!
}

我的目标是省略 Runway 一侧的导航属性(我不需要指向 Airport 的链接)。

但是当我使用dotnet-ef migrations add InitialCreate 命令时,会在数据库中为Runway 表创建一个AirportId 字段。 如何使用 EF Core 5 仅在一侧(在集合端)配置与导航属性的一对多关系?

similar question,但用于集合端的导航属性。

我尝试了以下但没有成功(没有任何变化):

modelBuilder.Entity<Airport>()
.HasMany<Runway>(a => a.Runways)
.WithOne()
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();

【问题讨论】:

  • 在您决定删除它之前,您的初始迁移之一中是否包含 airportId 字段?因为如果您从未指定该列,我认为没有理由将其包含在您的数据库中。
  • 在一对多中,您需要在多个边表中的外键。在Runaway 表中有AirportId 是正常的。
  • EF 将在Runway 表中创建一个可为空的AirportId 外键列,即使您删除了属性和关系配置代码。您如何期望数据库在没有外键列的情况下跟踪哪个Runway 属于哪个Airport?外键列是一对多关系的核心概念。
  • @Qudus - 不,不是。我没有以前的迁移。

标签: c# .net-core entity-framework-core


【解决方案1】:

外键列是具有功能性一对多关系的核心概念。数据库需要它来识别哪个子实体(Runway)属于哪个父实体(Airport)。因此,您无法避免。

如果您不希望 Runway 类中的 AirportIdAirport 引用,您可以安全地删除它们并将模型用作 -

public class Airport
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual IList<Runway> Runways { get; set; }
}

public class Runway
{
    public int Id { get; set; }    
    public string Name { get; set; }
}

您甚至可以删除关系配置代码。 EF 会自动在Runway 表中创建一个可为空的外键列AirportId,并在后台将其用作Shadow property(您无法访问)来管理关系。

【讨论】:

  • 看来是我的错。我有 existing 由 EF 6.4 创建的数据库。我正在将我的代码迁移到 EF Core 5。我预计 EF 6.4.4 没有在 Runway 表中创建导航属性。事实上,它创建的,但名称不同 - Airport_Id。这就是从现有数据库中读取导航字段并通过 EF Core 5 在表之间建立连接的问题。
  • 所以我以builder.Entity&lt;Airport&gt;().HasMany(a =&gt; a.Runways) .WithOne().HasForeignKey("Airport_Id").OnDelete(DeleteBehavior.Cascade).IsRequired();结束了
猜你喜欢
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 2022-10-25
  • 1970-01-01
相关资源
最近更新 更多