【发布时间】: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 无法确定 User 和 City 之间的一对多关系,它认为存在一对一关系(我记得我没有这样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