如何修复实体框架中的“无法确定导航属性表示的关系”错误
Posted
技术标签:
【中文标题】如何修复实体框架中的“无法确定导航属性表示的关系”错误【英文标题】:How to fix 'Unable to determine the relationship represented by navigation property' error in Entity Framework 【发布时间】:2019-09-01 21:22:56 【问题描述】:当我尝试在我的 .NET Core 2.1 网站上注册用户(使用身份)时,我收到以下错误:
“InvalidOperationException:无法确定由“ICollection”类型的导航属性“City.ConnectionStartCity”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“EntityTypeBuilder”忽略此属性。 'OnModelCreating' 中的忽略'。”。
发生这种情况的原因可能与身份无关,但注册和登录是目前我知道如何触发它的唯一方法。
我仍然希望在我的课程中使用“City”和“ICollection”属性,所以我不想使用“[NotMapped]”属性。
我在网上搜索,发现这是多对多关系造成的,我觉得不是这样。
“连接”类:
public partial class Connection
public Connection()
ConnectionRoute = new HashSet<ConnectionRoute>();
public int Id get; set;
public int StartCityId get; set;
public int EndCityId get; set;
public int AantalMinuten get; set;
public double Prijs get; set;
public Stad StartCity get; set;
public Stad EndCity get; set;
public ICollection<ConnectionRoute> ConnectionRoute get; set;
“城市”类:
public partial class City
public City()
AspNetUsers = new HashSet<AspNetUsers>();
Hotel = new HashSet<Hotel>();
ConnectionStartCity = new HashSet<Connection>();
ConnectionEndCity= new HashSet<Connection>();
public int Id get; set;
public string Name get; set;
public string Country get; set;
public ICollection<AspNetUsers> AspNetUsers get; set;
public ICollection<Hotel> Hotel get; set;
public ICollection<Connection> ConnectionStartCity get; set;
public ICollection<Connection> ConnectionEndCity get; set;
类 'treinrittenContext' (dbContext) 提取:
public virtual DbSet<City> City get; set;
public virtual DbSet<Connection> Connection get; set;
protected override void OnModelCreating(ModelBuilder modelBuilder)
...
modelBuilder.Entity<City>(entity =>
entity.Property(e => e.Country)
.IsRequired()
.HasMaxLength(255)
.IsUnicode(false);
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(255)
.IsUnicode(false);
entity.HasMany(p => p.ConnectionStartcity)
.WithOne(d => d.StartCity)
.HasForeignKey(d => d.StartCityId);
entity.HasMany(p => p.ConnectionEndCity)
.WithOne(d => d.EndCity)
.HasForeignKey(d => d.EndCityId);
);
...
modelBuilder.Entity<Connection>(entity =>
entity.HasOne(d => d.StartCity)
.WithMany(p => p.ConnectionStartCity)
.HasForeignKey(d => d.StartCityId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Verbinding_BeginStad");
entity.HasOne(d => d.EndCity)
.WithMany(p => p.ConnectionEndCity)
.HasForeignKey(d => d.EndCityId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Verbinding_EindStad");
);
...
我希望这会起作用(因为在我看来,这是一对多的关系),但事实并非如此。
【问题讨论】:
您还应该考虑您的命名,集合应该是多个(meervoud),例如您的 DbSet 应该是 Connections 和 Cities 以及您的属性 ConnectionStartCity 和 ConnectionEndCity。至于错误,可能是因为您缺少 StartCity 和 EndCity 上的 [必需] 注释。 @Dimitri,感谢您提供有关命名约定的提示。在 Connection 中为 StartCity 和 EndCity 添加 [Required] 注释并没有解决。 【参考方案1】:更新
这里有多种选择:
选项 1 结果为 1
城市等级变为:
public partial class City
public City()
Connections = new HashSet<Connection>();
public int Id get; set;
public string Name get; set;
public string Country get; set;
public ICollection<Connection> Connections get; set;
连接类变为:
public partial class Connection
public Connection()
public int Id get; set;
public int StartCityId get; set;
public int EndCityId get; set;
public int AantalMinuten get; set;
public double Prijs get; set;
您的 OnModelCreating 变为:
modelBuilder.Entity<City>().HasMany(city => city.Connections)
.WithRequired().HasForeignKey(con => con.EndCityId);
modelBuilder.Entity<City>().HasMany(city => city.Connections)
.WithRequired().HasForeignKey(con => con.StartCityId);
或者您也可以执行类似的操作,其中选项 2 的结果为 2:
城市等级变为:
public partial class City
public City()
Connections = new HashSet<Connection>();
public int Id get; set;
public string Name get; set;
public string Country get; set;
public ICollection<Connection> Connections get; set;
连接类变为:
public partial class Connection
public Connection()
public int Id get; set;
public virtual ICollection<City> Cities get; set;
public int AantalMinuten get; set;
public double Prijs get; set;
而且您无需在 OnModelCreating 中执行任何操作。
【讨论】:
我刚刚意识到我在我的问题中留下了一些未翻译的单词。那是我对不起!我更新了它,所以现在它应该更有意义了。 City 只是一个城市表(在我的例子中是伦敦,布鲁塞尔,......),连接应该是 2 个城市之间的连接(例如“伦敦到布鲁塞尔”或“布鲁塞尔到巴黎”)。因此,在 City 中,我想要一个以城市为起点的连接列表和一个以城市为终点的连接列表。完整的数据库模型(Stad = City 和 Verbinding = Connection):gyazo.com/8211bb2789e0f7a864aee1a6b9e21192 当我尝试第一个选项时,我在构建时收到此错误:“无法在 'City.Connection' 和 'Connection.EndCity' 之间创建关系,因为 'City.Connection' 之间已经存在关系。 Connection' 和 'Conncection.StartCity'。导航属性只能参与单个关系。”使用第二种解决方案,我失去了哪个城市是起点,哪个城市是终点。在这种情况下,它们的顺序很重要。 收集城市应该是虚拟的。 我同意第二种解决方案不适用于您的情况。至于错误,奇怪,没有发生在我这边。您是否启用了迁移?如果是这样,请更新您的模型。如果没有,你能告诉我你的 onmodelcreating 有什么,最终你的类现在是什么样子吗? @Dimitri 感谢您的回复以上是关于如何修复实体框架中的“无法确定导航属性表示的关系”错误的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Java 中的“禁用 XML 外部实体 (XXE) 处理”漏洞
如何修复 ApplicationUserManager 中的“LINQ to Entities 中不支持指定的类型成员‘UserId’”