C# 如何在EF Core中创建关系?
我正在构建一个ASP.NET Core 2.0应用程序,它有一个Web API后端和一个Angular 5前端。对于我的数据访问层,我使用实体框架核心 例如,我下面有两个模型,它们之间有关系C# 如何在EF Core中创建关系?,c#,asp.net-core,entity-framework-4.1,C#,Asp.net Core,Entity Framework 4.1,我正在构建一个ASP.NET Core 2.0应用程序,它有一个Web API后端和一个Angular 5前端。对于我的数据访问层,我使用实体框架核心 例如,我下面有两个模型,它们之间有关系 public class Project { [Key] public int Id { get; set; } public string project_name { get; set; } [ForeignKey("Person")] public in
public class Project
{
[Key]
public int Id { get; set; }
public string project_name { get; set; }
[ForeignKey("Person")]
public int? pm_person_id { get; set; }
[ForeignKey("Person")]
public int? ptl_person_id { get; set; }
[ForeignKey("pm_person_id")]
public virtual Person pm_person { get; set; }
[ForeignKey("ptl_person_id")]
public virtual Person ptl_person { get; set; }
}
public class Person
{
public Person()
{
pm_projects = new HashSet<Project>();
ptl_projects = new HashSet<Project>();
}
[Key]
public int Id { get; set; }
public string full_name { get; set; }
[ForeignKey("pm_person_id")]
public virtual ICollection<Project> pm_projects { get; set; }
[ForeignKey("ptl_person_id")]
public virtual ICollection<Project> ptl_projects { get; set; }
}
公共类项目
{
[关键]
公共int Id{get;set;}
公共字符串项目名称{get;set;}
[外籍人士(“人士”)]
公共int?pm_person_id{get;set;}
[外籍人士(“人士”)]
公共int?ptl_person_id{get;set;}
[外键(“pm人员id”)]
公共虚拟人pm_Person{get;set;}
[外国钥匙(“ptl_人员id”)]
公共虚拟人ptl_Person{get;set;}
}
公共阶层人士
{
公众人士()
{
pm_projects=newhashset();
ptl_projects=new HashSet();
}
[关键]
公共int Id{get;set;}
公共字符串全名{get;set;}
[外键(“pm人员id”)]
公共虚拟ICollection pm_项目{get;set;}
[外国钥匙(“ptl_人员id”)]
公共虚拟ICollection ptl_项目{get;set;}
}
但是,当我尝试连接到数据库并检索这些数据以显示时,EF Core表示它不了解Project.pm\u person\u id
和person
之间的关系
我遵循了有关EF Core的microsoft文档,建议使用ForeignKey属性,而不是在ModelBuilder中定义这些属性。我是否正确地完全建立了关系?在类项目中,您必须使用
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
类项目的建模方式如下:
[ForeignKey("pm_person_id")]
public int pm_person_id { get; set; }
public Person Person { get; set; }
并在类Person中添加icollection
public ICollection<Project> Project { get; set; }
公共ICollection项目{get;set;}
试试这个 对于每个外键,放置一个id属性和一个数据类型为外键类的属性,您不需要任何注释。实体框架会理解它是一个外键
public class Project
{
public int ID { get; set; }
public string projectName { get; set; }
public int? pmPersonID { get; set; }
public Person pmPerson { get; set; }
public int? ptlPersonID { get; set; }
public Person ptlPerson { get; set; }
}
public class Person
{
public Person()
{
pm_projects = new HashSet<Project>();
ptl_projects = new HashSet<Project>();
}
public int ID { get; set; }
public string fullName { get; set; }
public int pmPersonId { get; set; }
public virtual ICollection<Project> pmProjects { get; set; }
public int ptlProjectsId { get; set; }
public virtual ICollection<Project> ptlProjects { get; set; }
公共类项目
{
公共int ID{get;set;}
公共字符串projectName{get;set;}
公共int?pmPersonID{get;set;}
公共人物pmPerson{get;set;}
公共int?ptlPersonID{get;set;}
公众人物{get;set;}
}
公共阶层人士
{
公众人士()
{
pm_projects=newhashset();
ptl_projects=new HashSet();
}
公共int ID{get;set;}
公共字符串全名{get;set;}
公共int pmPersonId{get;set;}
公共虚拟ICollection项目{get;set;}
公共int-ptlProjectsId{get;set;}
公共虚拟ICollection项目{get;set;}
}不确定您在这里寻找的是什么,但这是一个更深入的示例,可能会有所帮助
public class Person
{
public Person()
{
PM_Projects = new HashSet<Project>();
PTL_Projects = new HashSet<Project>();
}
[Key]
[Required]
public int Id { get; set; }
public string Full_Name { get; set; }
public virtual ICollection<Project> PM_Projects { get; set; }
public virtual ICollection<Project> PTL_Projects { get; set; }
}
public class Project
{
[Key]
[Required]
public int Id { get; set; }
public string Project_Name { get; set; }
[ForeignKey("PM_Person")]
public int PM_Person_Id { get; set; }
[ForeignKey("PTL_Person")]
public int PTL_Person_Id { get; set; }
public virtual Person PM_Person { get; set; }
public virtual Person PTL_Person { get; set; }
}
在
Person
类上添加并运行迁移,尝试将[ForeignKey(“ptl_Person_id”)]
更改为[ForeignKey(“ptl_Person”)]
,同样,也可以将[ForeignKey(“pm_Person_id”)]
(同样在Person
上)更改为[ForeignKey(“ptl_Person”)]
。对堆栈交换进行应答检查。这个答案(虽然可能是正确的)可能会受益于对解决方案背后的推理的进一步解释。[ForeignKey]
属性不正确。您需要将该属性应用于Person
属性。您所做的是创建一个对自身的外键引用,这可能是OP出现问题的原因。为什么他们需要使用builder.property(t=>t.Full\u Name)
添加属性?甚至当数据库已经构建好时,还需要这些吗?
public class PersonMap : IEntityTypeConfiguration<Person>
{
public void Configure(EntityTypeBuilder<Person> builder)
{
builder.Property(t => t.Full_Name);
//table
builder.ToTable("People");
//relationships
builder.HasMany(s => s.PM_Projects).WithOne(o=>o.PM_Person).OnDelete(DeleteBehavior.Restrict);
builder.HasMany(s => s.PTL_Projects).WithOne(o => o.PTL_Person).OnDelete(DeleteBehavior.Restrict);
}
}
public class ProjectMap : IEntityTypeConfiguration<Project>
{
public void Configure(EntityTypeBuilder<Project> builder)
{
builder.Property(t => t.Project_Name);
//table
builder.ToTable("Projects");
//relationships
builder.HasOne(s => s.PM_Person).WithMany(d=>d.PM_Projects).OnDelete(DeleteBehavior.Restrict);
builder.HasOne(s => s.PTL_Person).WithMany(d => d.PTL_Projects).OnDelete(DeleteBehavior.Restrict);
}
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
//Build identity
BuildIdentity(builder);
builder.ApplyConfiguration(new PersonMap());
builder.ApplyConfiguration(new ProjectMap());
}