Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF同一主键上的多个外键关系_C#_Entity Framework_Entity Framework 6 - Fatal编程技术网

C# EF同一主键上的多个外键关系

C# EF同一主键上的多个外键关系,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,我想使用EF6创建一个多对多关系,使用代码优先的方法。我的实体使用复合主键(处理多租户) 让我们举一个简单而经典的例子。我有两个实体Project和Person,它们具有多对多关系: public class Person { [Key, Column(Order = 1),] public Int32 Id { get; set; } [Key, Column(Order = 2)] public int TenantId { get; set; } publi

我想使用EF6创建一个多对多关系,使用代码优先的方法。我的实体使用复合主键(处理多租户)

让我们举一个简单而经典的例子。我有两个实体
Project
Person
,它们具有多对多关系:

public class Person
{
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; } 
   [Key, Column(Order = 2)]
   public int TenantId { get; set; }
   public string Name { get; set; }
}

public class Project
{
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; } 
   [Key, Column(Order = 2)]
   public int TenantId { get; set; }
   Public string Name { get; set; }
}
我还有一个连接表
ProjectPerson
,如下所示:

上面我定义了一个
Project
ProjectPerson
的关系。请注意,公共类ProjectPerson { [键,列(顺序=1),] 公共Int32 Id{get;set;} [键,列(顺序=2)] [外键(“项目”)] public int TenantId{get;set;}

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

   public DateTime AddedDate{ get; set; }

   public virtual Project Project { get; set; }
}
TenantId
用作主键和外键的一部分

 public class ProjectPerson
 {
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; } 
   [Key, Column(Order = 2)]
   [ForeignKey("Project")]
   public int TenantId { get; set; }

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

   [ForeignKey("Person")]
   public int PersonId { get; set; }
   [ForeignKey("Person")]
   public int PersonTenantId { get; set; } // duplicate 


   public DateTime AddedDate{ get; set; }

   public virtual Project Project { get; set; }
   public virtual Person Person { get; set; }

}
到目前为止,模型按预期工作。但是缺少
Person
ProjectPerson
的关系

我在
ProjectPerson
类中添加了以下两行

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

  public virtual Person Person { get; set; }
确实缺少到
TenantId
的映射。我不知道如何定义它

更新

我找到了这个。但是我仍然不满意,因为有额外的TenantId(
PersontenatID
)作为外键

 public class ProjectPerson
 {
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; } 
   [Key, Column(Order = 2)]
   [ForeignKey("Project")]
   public int TenantId { get; set; }

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

   [ForeignKey("Person")]
   public int PersonId { get; set; }
   [ForeignKey("Person")]
   public int PersonTenantId { get; set; } // duplicate 


   public DateTime AddedDate{ get; set; }

   public virtual Project Project { get; set; }
   public virtual Person Person { get; set; }

}

使用fluent API为联接表中的两个FK重用
tentandi
列。
ProjectId
也应包含在联接表的PK中。请注意,我修改了复合主键列的顺序,将
TenantId
作为第一列

    public class Person
    {
        [Key, Column(Order = 0)]
        public int TenantId { get; set; }
        [Key, Column(Order = 1)]
        public int PersonId { get; set; }

        public string Name { get; set; }

        public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }
    }

    public class Project
    {
        [Key, Column(Order = 0)]
        public int TenantId { get; set; }
        [Key, Column( Order = 1 )]
        public int ProjectId { get; set; }

        public string Name { get; set; }

        public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }
    }

    public class ProjectPerson
    {
        [Key, Column( Order = 0 )]
        public int TentantId { get; set; }
        [Key, Column( Order = 1 )]
        public int ProjectId { get; set; }
        [Key, Column( Order = 2 )]
        public int PersonId { get; set; }

        public DateTime AddedDate { get; set; }

        public virtual Project Project { get; set; }
        public virtual Person Person { get; set; }
    }


    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {
        base.OnModelCreating( modelBuilder );

        modelBuilder.Entity<Project>()
            .HasMany(pr => pr.ProjectPeople )
            .WithRequired( pp => pp.Project )
            .HasForeignKey( pp => new { pp.TentantId, pp.ProjectId } );

        modelBuilder.Entity<Person>()
            .HasMany( pe => pe.ProjectPeople )
            .WithRequired( pp => pp.Person )
            .HasForeignKey( pp => new { pp.TentantId, pp.PersonId } );
    }
公共类人物
{
[键,列(顺序=0)]
public int TenantId{get;set;}
[键,列(顺序=1)]
公共int PersonId{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection项目人员{get;set;}
}
公共类项目
{
[键,列(顺序=0)]
public int TenantId{get;set;}
[键,列(顺序=1)]
公共int ProjectId{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection项目人员{get;set;}
}
公共类项目人员
{
[键,列(顺序=0)]
公共整数{get;set;}
[键,列(顺序=1)]
公共int ProjectId{get;set;}
[键,列(顺序=2)]
公共int PersonId{get;set;}
公共日期时间添加数据{get;set;}
公共虚拟项目{get;set;}
公共虚拟人{get;set;}
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity()
.HasMany(pr=>pr.ProjectPeople)
.WithRequired(pp=>pp.项目)
.HasForeignKey(pp=>new{pp.tentandi,pp.ProjectId});
modelBuilder.Entity()
.HasMany(pe=>pe.ProjectPeople)
.WithRequired(pp=>pp.个人)
.HasForeignKey(pp=>new{pp.tentandi,pp.PersonId});
}

为什么您需要ProjectPerson中的TenancId映射,您已经在project表和person表中都有了映射?就ProjectPerson而言,TenantId是不相关的。它只是一个关联表,给定的租户只能查询其租约中的项目或人员,对吗?您不需要此TenancId成为其中的一部分如果你试图强制它,这个表将以一个3表连接结束。除了这个@rism之外,还有两个原因:1.没有ProjectPerson中的TenantId,我们无法在DBMS中创建外键关联。2.租户数据应该能够在数据库之间移动。也就是说,每个记录都应该是唯一的。我按照上的说明进行了操作,但得到了以下信息lowing error
映射不足:外键必须映射到一些概念上参与外键关联的AssociationSet或EntitySet。
您是说您已经设置了密钥,以便TenantA可以拥有ID=1的个人,而TenantB也可以拥有ID=1的独特个人记录?完全正确。特别是在fol中低电平情况。映像租户和租户在DB X中,而租户在DB Y中。稍后租户在DB Y中移动