C# 实体框架核心无法确定关系
在我的ASP.Net Core 3.1应用程序中,我想定义一个协作室和一个人员模型,其中每个协作室可以有一个代表和多个Person类型的委托,但我遇到了“无法确定导航属性'Facility.delegates'表示的关系'List'类型”错误C# 实体框架核心无法确定关系,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,在我的ASP.Net Core 3.1应用程序中,我想定义一个协作室和一个人员模型,其中每个协作室可以有一个代表和多个Person类型的委托,但我遇到了“无法确定导航属性'Facility.delegates'表示的关系'List'类型”错误 公共类设施 { 公共int Id{get;set;} 公共字符串代码{get;set;} 公共字符串名称{get;set;} 公共字符串地址{get;set;} 公共字符串电子邮件{get;set;} 公用字符串电话{get;set;} 公共字符串活动{g
公共类设施
{
公共int Id{get;set;}
公共字符串代码{get;set;}
公共字符串名称{get;set;}
公共字符串地址{get;set;}
公共字符串电子邮件{get;set;}
公用字符串电话{get;set;}
公共字符串活动{get;set;}
public int RepresentativeId{get;set;}
公众人物代表{get;set;}
公共列表委托{get;set;}
}
公共类人物
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
公用字符串电话{get;set;}
[反向财产(“代表”)]
public List RepresentedFacilities{get;set;}
[反向属性(“代表”)]
公共列表已委派的功能{get;set;}
}
如何正确地完成这个映射?我的问题有更好的解决方案吗?要获得多对多关系,您需要添加一个课堂设施Person:
[Keyless]
public class FacilityPerson
{
public int PersonId { get; set; }
public Person Person { get; set; }
public int FacilityId { get; set; }
public Facility Facility{ get; set; }
}
公共类设施
{
…//其他属性
公共列表委托{get;set;}
}
公共阶层人士
{
…//其他属性
[反向财产(“代表”)]
public List RepresentedFacilities{get;set;}
[反向属性(“代表”)]
公共列表已委派的功能{get;set;}
}
在Entity Framework的早期版本中,此模型定义(使用上述代码)足以让EF暗示正确的关系类型并为其生成联接表。在3.x之前(含3.x)的EF Core中,需要在模型中包含一个实体来表示联接表,然后将导航属性添加到指向联接实体的多对多关系的任一侧。因此,请尝试按以下方式修改您的代码:
public class Facility
{
[Key]
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Activity { get; set; }
public int RepresentativeId { get; set; }
public Person Representative { get; set; }
public List<PersonFacilities> PersonFacilities { get; set; }
}
public class Person
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
[InverseProperty("Representative")]
public List<PersonFacilities> RepresentedFacilities { get; set; }
[InverseProperty("Delegates")]
public List<PersonFacilities> DelegatedToFacilities { get; set; }
}
public class PersonFacilities
{
//public int PersonId { get; set; }
//public Person Person { get; set; }
public int FacilityId { get; set; }
public Facility Facility { get; set; }
public int RepresentactivePersonId { get; set; }
public Person Representative { get; set; }
public int DelegatePersonId { get; set; }
public Person Delegates { get; set; }
}
公共类设施
{
[关键]
公共int Id{get;set;}
公共字符串代码{get;set;}
公共字符串名称{get;set;}
公共字符串地址{get;set;}
公共字符串电子邮件{get;set;}
公用字符串电话{get;set;}
公共字符串活动{get;set;}
public int RepresentativeId{get;set;}
公众人物代表{get;set;}
公共列表PersonFacilities{get;set;}
}
公共阶层人士
{
[关键]
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
公用字符串电话{get;set;}
[反向财产(“代表”)]
public List RepresentedFacilities{get;set;}
[反向属性(“代表”)]
公共列表已委派的功能{get;set;}
}
公共类人事设施
{
//公共int PersonId{get;set;}
//公众人物{get;set;}
公共int设施ID{get;set;}
公共设施设施{get;set;}
public int representativepersonid{get;set;}
公众人物代表{get;set;}
public int DelegatePersonId{get;set;}
公共人物委托{get;set;}
}
联接表将按照约定以联接实体命名。该关系还需要通过Fluent API进行配置,以便EF Core能够成功映射:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PersonFacilities>().HasKey(pf => new { pf.FacilityId, pf.DelegatePersonId, pf.RepresentactivePersonId });
modelBuilder.Entity<PersonFacilities>()
.HasOne(pf => pf.Representative).WithMany(p => p.RepresentedFacilities)
.HasForeignKey(pf => pf.RepresentactivePersonId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PersonFacilities>().HasOne(pf => pf.Delegates).WithMany(p => p.DelegatedToFacilities)
.HasForeignKey(pf => pf.DelegatePersonId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PersonFacilities>().HasOne(pf => pf.Facility).WithMany(p => p.PersonFacilities)
.HasForeignKey(pf => pf.FacilityId).OnDelete(DeleteBehavior.Restrict);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().HasKey(pf=>new{pf.FacilityId,pf.DelegatePersonId,pf.representativepersonid});
modelBuilder.Entity()
.HasOne(pf=>pf.RepresentedFacilities)。有许多(p=>p.RepresentedFacilities)
.HasForeignKey(pf=>pf.representativepersonid).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity().HasOne(pf=>pf.delegated).WithMany(p=>p.DelegatedToFacilities)
.HasForeignKey(pf=>pf.DelegatePersonId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity().HasOne(pf=>pf.Facility).WithMany(p=>p.personfacility)
.HasForeignKey(pf=>pf.FacilityId).OnDelete(DeleteBehavior.Restrict);
}
然后,在迁移之后,结果如下:
参考:
这是一种多对多的关系,您需要遵循这一点回答您的问题吗?只有当一个人可以被委派到多个设施时,这才是多对多。是这样吗?
public class Facility
{
...//other properties
public List<Person> Delegates { get; set; }
}
public class Person
{
...//other properties
[InverseProperty("Representative")]
public List<Facility> RepresentedFacilities { get; set; }
[InverseProperty("Delegates")]
public List<Facility> DelegatedToFacilities { get; set; }
}
public class Facility
{
[Key]
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Activity { get; set; }
public int RepresentativeId { get; set; }
public Person Representative { get; set; }
public List<PersonFacilities> PersonFacilities { get; set; }
}
public class Person
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
[InverseProperty("Representative")]
public List<PersonFacilities> RepresentedFacilities { get; set; }
[InverseProperty("Delegates")]
public List<PersonFacilities> DelegatedToFacilities { get; set; }
}
public class PersonFacilities
{
//public int PersonId { get; set; }
//public Person Person { get; set; }
public int FacilityId { get; set; }
public Facility Facility { get; set; }
public int RepresentactivePersonId { get; set; }
public Person Representative { get; set; }
public int DelegatePersonId { get; set; }
public Person Delegates { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PersonFacilities>().HasKey(pf => new { pf.FacilityId, pf.DelegatePersonId, pf.RepresentactivePersonId });
modelBuilder.Entity<PersonFacilities>()
.HasOne(pf => pf.Representative).WithMany(p => p.RepresentedFacilities)
.HasForeignKey(pf => pf.RepresentactivePersonId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PersonFacilities>().HasOne(pf => pf.Delegates).WithMany(p => p.DelegatedToFacilities)
.HasForeignKey(pf => pf.DelegatePersonId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PersonFacilities>().HasOne(pf => pf.Facility).WithMany(p => p.PersonFacilities)
.HasForeignKey(pf => pf.FacilityId).OnDelete(DeleteBehavior.Restrict);
}