C# 实体框架-多外键问题

C# 实体框架-多外键问题,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我有一个Project模型,它有一个ProjectLead(一个Person外键的实例),这很好用。但是现在我还需要添加一个人员(项目成员)集合,引用相同的人员表,我无法获取实体框架来生成数据库。当我尝试添加Fluent API代码以创建链接表ProjectPerson时,我收到一个错误-“指定的架构无效。错误:由于类型“MyApp.WebApi.Models.Person”不可用,因此未加载关系“MyApp.WebApi.Models.Person”我认为这是因为与ProjectLead已有F

我有一个
Project
模型,它有一个
ProjectLead
(一个
Person
外键的实例),这很好用。但是现在我还需要添加一个
人员
(项目成员)集合,引用相同的
人员
表,我无法获取实体框架来生成数据库。当我尝试添加Fluent API代码以创建链接表
ProjectPerson
时,我收到一个错误-“指定的架构无效。错误:由于类型“MyApp.WebApi.Models.Person”不可用,因此未加载关系“MyApp.WebApi.Models.Person”我认为这是因为与
ProjectLead
已有FK关系

项目模型:

public class Project
{
    [Key]
    public int ProjectId { get; set; }

    public string Name { get; set; }

    // Foreign Key - Project lead (Person)
    public int ProjectLeadId { get; set; }
    public virtual Person ProjectLead { get; set; }

    // Create many to many relationship with People - Team members on this project
    public ICollection<Person> People { get; set; }

    public Project()
    {
        People = new HashSet<Person>();
    }
}
public class Person
{
    [Key]
    public int PersonId { get; set; }

    public String Firstname { get; set; }
    public String Surname { get; set; }

    // Create many to many relationship
    public ICollection<Project> Projects { get; set; }

    public Person()
    {
        Projects = new HashSet<Project>();
    }
}
public class HerculesWebApiContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Project> Projects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // This works fine
        modelBuilder.Entity<Project>()
                    .HasRequired(c => c.ProjectLead)
                    .WithMany(d => d.Projects)
                    .HasForeignKey(c => c.ProjectLeadId)
                    .WillCascadeOnDelete(false);

        // Adding these lines to create the link table `PersonProjects` causes an error

        //modelBuilder.Entity<Person>().HasMany(t => t.Projects).WithMany(t => t.People);

        //modelBuilder.Entity<Project>().HasMany(t => t.People).WithMany(t => t.Projects);
    }
}
公共类项目
{
[关键]
公共int ProjectId{get;set;}
公共字符串名称{get;set;}
//外键-项目负责人(人)
public int ProjectLeadId{get;set;}
公共虚拟人ProjectLead{get;set;}
//与此项目的人员-团队成员建立多对多关系
公共ICollection人员{get;set;}
公共工程()
{
People=newhashset();
}
}
人物模型:

public class Project
{
    [Key]
    public int ProjectId { get; set; }

    public string Name { get; set; }

    // Foreign Key - Project lead (Person)
    public int ProjectLeadId { get; set; }
    public virtual Person ProjectLead { get; set; }

    // Create many to many relationship with People - Team members on this project
    public ICollection<Person> People { get; set; }

    public Project()
    {
        People = new HashSet<Person>();
    }
}
public class Person
{
    [Key]
    public int PersonId { get; set; }

    public String Firstname { get; set; }
    public String Surname { get; set; }

    // Create many to many relationship
    public ICollection<Project> Projects { get; set; }

    public Person()
    {
        Projects = new HashSet<Project>();
    }
}
public class HerculesWebApiContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Project> Projects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // This works fine
        modelBuilder.Entity<Project>()
                    .HasRequired(c => c.ProjectLead)
                    .WithMany(d => d.Projects)
                    .HasForeignKey(c => c.ProjectLeadId)
                    .WillCascadeOnDelete(false);

        // Adding these lines to create the link table `PersonProjects` causes an error

        //modelBuilder.Entity<Person>().HasMany(t => t.Projects).WithMany(t => t.People);

        //modelBuilder.Entity<Project>().HasMany(t => t.People).WithMany(t => t.Projects);
    }
}
公共类人物
{
[关键]
公共int PersonId{get;set;}
公共字符串名{get;set;}
公共字符串姓氏{get;set;}
//创建多对多关系
公共ICollection项目{get;set;}
公众人士()
{
Projects=newhashset();
}
}
DB上下文:

public class Project
{
    [Key]
    public int ProjectId { get; set; }

    public string Name { get; set; }

    // Foreign Key - Project lead (Person)
    public int ProjectLeadId { get; set; }
    public virtual Person ProjectLead { get; set; }

    // Create many to many relationship with People - Team members on this project
    public ICollection<Person> People { get; set; }

    public Project()
    {
        People = new HashSet<Person>();
    }
}
public class Person
{
    [Key]
    public int PersonId { get; set; }

    public String Firstname { get; set; }
    public String Surname { get; set; }

    // Create many to many relationship
    public ICollection<Project> Projects { get; set; }

    public Person()
    {
        Projects = new HashSet<Project>();
    }
}
public class HerculesWebApiContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Project> Projects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // This works fine
        modelBuilder.Entity<Project>()
                    .HasRequired(c => c.ProjectLead)
                    .WithMany(d => d.Projects)
                    .HasForeignKey(c => c.ProjectLeadId)
                    .WillCascadeOnDelete(false);

        // Adding these lines to create the link table `PersonProjects` causes an error

        //modelBuilder.Entity<Person>().HasMany(t => t.Projects).WithMany(t => t.People);

        //modelBuilder.Entity<Project>().HasMany(t => t.People).WithMany(t => t.Projects);
    }
}
公共类herculesWebAPI上下文:DbContext
{
公共数据库集人物{get;set;}
公共数据库集项目{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
//这个很好用
modelBuilder.Entity()
.HasRequired(c=>c.ProjectLead)
.有许多(d=>d.项目)
.HasForeignKey(c=>c.ProjectLeadId)
.WillCascadeOnDelete(假);
//添加这些行以创建链接表“PersonProjects”会导致错误
//modelBuilder.Entity()有许多(t=>t.Projects)。有许多(t=>t.People);
//modelBuilder.Entity()有许多(t=>t.People)。有许多(t=>t.Projects);
}
}

我想我可能需要使用
InverseProperty
属性,但我不确定在这种情况下应该使用哪个属性?

您能明确定义联接表吗?所以,定义一个ProjectPeople关系,并使代码如下所示

 public class ProjectPerson{
    [Key]
    public int ProjectPersonId { get; set; }

    [ForeignKey("Project")]
    public int? ProjectId {get;set;}
    public virtual Project {get;set;}

    [ForeignKey("Person")]
    public int? PersonId {get;set;}
    public virtual Person {get;set;}

    public string RelationshipType {get;set;}
 }
public class Project
{
   [Key]
   public int ProjectId { get; set; }

   public string Name { get; set; }

   // Foreign Key - Project lead (Person)
   public int ProjectLeadId { get; set; }
   public virtual Person ProjectLead { get; set; }

   // Create many to many relationship with People - Team members on this project
   public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }

   public Project()
   {
       ProjectPerson = new HashSet<ProjectPerson>();
   }
然后你的另外两个班会像这样

 public class ProjectPerson{
    [Key]
    public int ProjectPersonId { get; set; }

    [ForeignKey("Project")]
    public int? ProjectId {get;set;}
    public virtual Project {get;set;}

    [ForeignKey("Person")]
    public int? PersonId {get;set;}
    public virtual Person {get;set;}

    public string RelationshipType {get;set;}
 }
public class Project
{
   [Key]
   public int ProjectId { get; set; }

   public string Name { get; set; }

   // Foreign Key - Project lead (Person)
   public int ProjectLeadId { get; set; }
   public virtual Person ProjectLead { get; set; }

   // Create many to many relationship with People - Team members on this project
   public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }

   public Project()
   {
       ProjectPerson = new HashSet<ProjectPerson>();
   }
公共类项目
{
[关键]
公共int ProjectId{get;set;}
公共字符串名称{get;set;}
//外键-项目负责人(人)
public int ProjectLeadId{get;set;}
公共虚拟人ProjectLead{get;set;}
//与此项目的人员-团队成员建立多对多关系
公共虚拟ICollection项目人员{get;set;}
公共工程()
{
ProjectPerson=newhashset();
}
}

还有这个

Public class Person
{
  [Key]
  public int PersonId { get; set; }

  public String Firstname { get; set; }
  public String Surname { get; set; }

  // Create many to many relationship
  public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }


  public Person()
  {
     ProjectPerson = new HashSet<ProjectPerson>();
  }
}
公共类人物
{
[关键]
公共int PersonId{get;set;}
公共字符串名{get;set;}
公共字符串姓氏{get;set;}
//创建多对多关系
公共虚拟ICollection项目人员{get;set;}
公众人士()
{
ProjectPerson=newhashset();
}
}

如果您能准确地说出您遇到的错误,可能会有所帮助。“导致错误”毫无意义。谢谢,在帖子中添加了错误消息。为什么还要添加流畅的配置?您的配置所做的与正常约定所做的相同。其次,您可能希望使您的收藏成为虚拟的,因为您可能不希望每次查询项目时都包括所有相关人员。@ErikFunkenbusch-谢谢,是的,我将使收藏成为虚拟的。我使用fluent API是因为我有一个非标准外键ID
ProjectLeadId
。谢谢,这是个好主意。那么,每次我用
人员
获取
项目
时,我如何避免收回整个
ProjectPeople
表?我会在我的控制器中这样做吗,比如
返回db.Projects.Include(“ProjectPeople”).Where(e=>e.projectd==id).AsEnumerable()可以,但在这种情况下,可以使用延迟加载,避免抢占关系并删除“Include”。然后,当你想查询你的加入关系时,你可以做大量的操作来过滤你的结果。(另外,作为提示,我将在视图模型中放置类似的内容,以防止控制器显式定义查询。)