【问题标题】:How do I create relationships in EF Core?如何在 EF Core 中创建关系?
【发布时间】:2018-04-19 19:16:14
【问题描述】:

我正在构建一个带有 Web API 后端和 Angular 5 前端的 ASP.NET Core 2.0 应用程序。对于我的数据访问层,我使用的是 Entity Framework Core。

例如,我下面有两个模型有关系。

 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; }
}

但是,当我尝试连接到数据库并检索这些以显示时,EF Core 表示它不理解 Project.pm_person_idPerson 之间的关系。

我遵循了 EF Core 上的 Microsoft 文档,它建议使用 ForeignKey 属性,而不是在 ModelBuilder 中定义这些属性。我是否完全正确地建立了关系?

【问题讨论】:

  • Person 类上,尝试将[ForeignKey("ptl_person_id")] 更改为[ForeignKey("ptl_person")],同样适用于[ForeignKey("pm_person_id")](也在Person 上)。

标签: c# asp.net-core entity-framework-4.1


【解决方案1】:

在类 Project 中你必须添加 using

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

类Project应该这样建模:

[ForeignKey("pm_person_id")]
public int pm_person_id { get; set; }
public Person Person { get; set; }

并在 Person 类中添加 collection

public ICollection<Project> Project { get; set; }

试试这个!

【讨论】:

  • 正在回答 Stack Exchange 的评论。这个答案(虽然可能是正确的)可能会受益于对解决方案背后原因的进一步解释。
  • [ForeignKey] 属性不正确。您需要将该属性应用于Person 属性。您所做的是创建对其自身的外键引用,这可能是 OP 出现问题的原因。
【解决方案2】:

为每个外键放置一个 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; }

}

【讨论】:

    【解决方案3】:

    不确定您在此处寻找的确切内容,但这是一个更深入的示例,可能会有所帮助。

    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; }
    }
    

    一些映射的类

    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());
    }
    

    添加并运行你的迁移

    【讨论】:

    • 为什么他们需要使用builder.Property(t =&gt; t.Full_Name) 添加的属性,并且在数据库已经构建好的情况下是否还需要这些属性?
    猜你喜欢
    • 2021-03-01
    • 2019-02-09
    • 2021-11-17
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2021-05-20
    相关资源
    最近更新 更多