我有这两个模型(不存在不相关的属性):
// 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,我们可以删除Users
内的City
导航属性,并调用一个空的WithMany
(请参阅第一个注释):
modelBuilder.Entity<User>()
.HasOne<City>(u => u.City)
.WithMany()
.HasForeignKey(u => u.CityId);
这是唯一的方法吗?我在做错什么吗?
编辑:我在EF 6版本的CreatorId
类上拥有更多的属性,例如LastEditorId
(例如Base
),它仍然可以关系。在EF Core版本中对此进行了尝试。无法正常工作。
答案 0 :(得分:1)
问题似乎是从City
模型继承的Base
包含父类的所有属性,因此City
和User
之间的关系是一对一的,而不是一对多的。
实际上,Entity Framework Core对于一对多关系遵循与Entity Framework 6.x约定相同的约定。唯一的区别是EF Core创建的外键列的名称与导航属性名称相同,而不是<NavigationPropertyName>_<PrimaryKeyPropertyName>
。
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