【问题标题】:EF Core one-to-many relationship beside another foreign key property另一个外键属性旁边的 EF Core 一对多关系
【发布时间】:2019-09-14 00:49:53
【问题描述】:

我有这两个模型(不存在不相关的属性):

// based on Identity
public class User {
  public long? CityId { get; set; }
  public virtual City City { get; set; }
}

public class City : Base {
}

public class Base {
  public string CreatorId { get; set; }
  public virtual User Creator { get; set; }
}

现在,问题是 EF Core 无法确定 UserCity 之间的一对多关系,它认为存在一对一关系(我记得我没有这样EF 6) 的问题。

无法确定一对一的孩子/依赖方 “User.City”和“City.Creator”之间的关系。识别 关系的子/依赖端,配置外键 财产。如果这些导航不应该是相同的一部分 关系配置它们而不指定逆。

所以,我不得不向City 添加另一个导航属性:

public class City : Base {
  public virtual IList<User> Users { get; set; }
}

但问题依然存在:

无法确定导航所代表的关系 “IList”类型的属性“City.Users”。要么手动配置 关系,或使用 '[NotMapped]' 忽略此属性 属性或在“OnModelCreating”中使用“EntityTypeBuilder.Ignore”。

我最终使用了 Fluent API 和 ModelBuilder

modelBuilder.Entity<User>()
            .HasOne<City>(u => u.City)
            .WithMany(c => c.Users)
            .HasForeignKey(u => u.CityId);

使用 Fluent API,我们可以删除 City 中的 Users 导航属性并调用一个空的 WithMany(参见第一条评论):

modelBuilder.Entity<User>()
            .HasOne<City>(u => u.City)
            .WithMany()
            .HasForeignKey(u => u.CityId);

这是唯一的方法吗?我做错了吗?

编辑:我在 EF 6 版本的 Base 类上有更多属性,例如 CreatorId(例如 LastEditorId),它仍然可以找出关系。在 EF Core 版本中尝试过这个。不工作。

【问题讨论】:

  • 您不需要 IList 用户,您可以将 withMany() 留空。我不明白你的问题你不喜欢使用流利的 api?
  • @CrazyBaran 谢谢。我不知道。我会更新问题。当真正需要 Fluent API 时,我喜欢它。我只想知道在这种情况下是否需要使用 Fluent API。它曾经在 EF 6 上工作。
  • 很难说我写了流畅的 api 来控制一切。但是,当您在每个站点上都有这样的构造一个属性时,它自然会认为它是一对一的。密钥是如何生成的?在用户中的示例中,您没有任何 ID。我以为这是什么东西。在 City 上,您也将其删除。它被命名为Id?
  • @CrazyBaran 为了清楚起见,它们已被删除。他们在两个模型上都被命名为Id
  • 所以根据我的理解,ef core 的行为很好,在这种情况下它是一对一的。没有什么额外的东西可以告诉 ef core 以不同的方式表现。所以我认为你需要留下流利的 api。

标签: c# asp.net-core .net-core ef-core-2.2


【解决方案1】:

问题似乎是Base模型继承的City包含了父类的所有属性,所以CityUser之间的关系是一对一的,不是一对多。

事实上,Entity Framework Core 遵循与实体框架 6.x 中一对多关系的约定相同的约定。唯一的区别是 EF Core 创建了一个与导航属性名称同名的外键列,而不是 &lt;NavigationPropertyName&gt;_&lt;PrimaryKeyPropertyName&gt;

Fluent API 指定您可以使用数据注释的模型配置以及一些数据注释无法实现的附加功能。

  • 在 Entity Framework Core 中,ModelBuilder 类充当 Fluent API。

  • 我们可以通过使用它来配置许多不同的东西,因为它提供了比数据注释属性更多的配置选项。

  • 数据注解和 Fluent API 可以一起使用,但优先级为 Fluent API > 数据注解 > 默认约定。

您可以参考以下链接以帮助您更好地了解 Fluent Api:

https://www.entityframeworktutorial.net/efcore/fluent-api-in-entity-framework-core.aspx

https://entityframeworkcore.com/model-fluent-api

【讨论】:

  • 谢谢。一些有用的信息。似乎是这样,但我不明白 EF 6 是如何做到这一点的。奇怪的是,我在 EF 6 版本的 Base 类上有更多的属性,如 CreatorId(例如 LastEditorId),它仍然有效。但我也在 E​​F Core 中尝试过;不工作。
猜你喜欢
  • 1970-01-01
  • 2017-05-01
  • 2022-10-25
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
相关资源
最近更新 更多