Entity framework 同一主键表的多个外键

Entity framework 同一主键表的多个外键,entity-framework,Entity Framework,我有一个包含多个字段的表,这些字段是另一个表中主键的外键。例如: Fixture Id (PK) HomeTeamId (FK to Team.TeamId) AwayTeamId (FK to Team.TeamId) HomeTeamCoachId (FK to Coach.CoachId) AwayTeamCoachId (FK to Coach.CoachId) 将此数据分成两个表HomeTeam和AwayTeam,并使用一个外键作为FixtureId,这样会更好吗?这是实体框架当前生

我有一个包含多个字段的表,这些字段是另一个表中主键的外键。例如:

Fixture Id (PK)
HomeTeamId (FK to Team.TeamId)
AwayTeamId (FK to Team.TeamId)
HomeTeamCoachId (FK to Coach.CoachId)
AwayTeamCoachId (FK to Coach.CoachId)
将此数据分成两个表HomeTeam和AwayTeam,并使用一个外键作为FixtureId,这样会更好吗?这是实体框架当前生成的内容:

FixtureId PK
HomeTeamId int
AwayTeamId int
HomeTeamCoachId int
AwayTeamCoachId int
AwayTeam_TeamId FK
HomeTeam_TeamId FK
AwayTeamCoach_CoachId FK
HomeTeamCoach_CoachId FK
这是通过此类生成的:

public partial class Fixture
{
    public int FixtureId { get; set; }

    //foreign key
    public int AwayTeamId { get; set; }
    //navigation properties
    public virtual Team AwayTeam { get; set; }

    //foreign key
    public int HomeTeamId { get; set; }
    //navigation properties
    public virtual Team HomeTeam { get; set; }

    //foreign key
    public int AwayCoachId { get; set; }
    //navigation properties
    public virtual Coach AwayCoach { get; set; }

    //foreign key
    public int HomeCoachId { get; set; }
    //navigation properties
    public virtual Coach HomeCoach { get; set; }
}
有人能告诉我这样做是否正确吗

编辑:回复Slauma

所以我的课程基本上是这样的?或者OnModelCreating中的配置是否意味着我不需要Fixture类中的一些外键相关代码

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Entity Type Configuration
        modelBuilder.Configurations.Add(new TeamConfiguration());
        modelBuilder.Configurations.Add(new CoachConfiguration());
        modelBuilder.Configurations.Add(new FixtureConfiguration());

        modelBuilder.Entity<Fixture>()
            .HasRequired(f => f.AwayTeam)
            .WithMany()
            .HasForeignKey(f => f.AwayTeamId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Fixture>()
            .HasRequired(f => f.HomeTeam)
            .WithMany()
            .HasForeignKey(f => f.HomeTeamId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Fixture>()
            .HasRequired(f => f.AwayCoach)
            .WithMany()
            .HasForeignKey(f => f.AwayCoachId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Fixture>()
            .HasRequired(f => f.HomeCoach)
            .WithMany()
            .HasForeignKey(f => f.HomeCoachId)
            .WillCascadeOnDelete(false);
    }

public partial class Fixture
{
    public int FixtureId { get; set; }
    public string Season { get; set; }
    public byte Week { get; set; }

    //foreign key
    public int AwayTeamId { get; set; }
    //navigation properties
    public virtual Team AwayTeam { get; set; }

    //foreign key
    public int HomeTeamId { get; set; }
    //navigation properties
    public virtual Team HomeTeam { get; set; }

    //foreign key
    public int AwayCoachId { get; set; }
    //navigation properties
    public virtual Coach AwayCoach { get; set; }

    //foreign key
    public int HomeCoachId { get; set; }
    //navigation properties
    public virtual Coach HomeCoach { get; set; }

    public byte AwayTeamScore { get; set; }
    public byte HomeTeamScore { get; set; }
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
//实体类型配置
modelBuilder.Configurations.Add(newteamconfiguration());
添加(新CoachConfiguration());
modelBuilder.Configurations.Add(newfixtureconfiguration());
modelBuilder.Entity()
.HasRequired(f=>f.AwayTeam)
.有很多
.HasForeignKey(f=>f.AwayTeamId)
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasRequired(f=>f.HomeTeam)
.有很多
.HasForeignKey(f=>f.HomeTeamId)
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasRequired(f=>f.AwayCoach)
.有很多
.HasForeignKey(f=>f.AwayCoachId)
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasRequired(f=>f.HomeCoach)
.有很多
.HasForeignKey(f=>f.HomeCoachId)
.WillCascadeOnDelete(假);
}
公共部分类固定装置
{
公共int FixtureId{get;set;}
公共字符串季节{get;set;}
公共字节周{get;set;}
//外键
公共int{get;set;}
//导航属性
公共虚拟团队AwayTeam{get;set;}
//外键
public int HomeTeamId{get;set;}
//导航属性
公共虚拟团队HomeTeam{get;set;}
//外键
公共int AwayCoachId{get;set;}
//导航属性
公共虚拟Coach AwayCoach{get;set;}
//外键
公共int HomeCoachId{get;set;}
//导航属性
公共虚拟Coach HomeCoach{get;set;}
公共字节AwayTeamScore{get;set;}
公共字节HomeTeamScore{get;set;}
}

显然,EF不会将
int
属性(如
AwayTeamId
)检测为导航属性(如
AwayTeam
)的外键,因为
Team
中的主键属性不是
Id
而是
TeamId
。如果FK的名称类似于
AwayTeamTeamId
,或者
Team
中的主键属性的名称为
Id
,则可能会检测到FK

如果不想根据EF约定更改这些特性名称,可以使用数据注释定义FK:

[ForeignKey("AwayTeam")]
public int AwayTeamId { get; set; }
public virtual Team AwayTeam { get; set; }

// the same for the other three FKs
或Fluent API:

modelBuilder.Entity<Fixture>()
    .HasRequired(f => f.AwayTeam)
    .WithMany()
    .HasForeignKey(f => f.AwayTeamId)
    .WillCascadeOnDelete(false);

// the same for the other three FKs
modelBuilder.Entity()
.HasRequired(f=>f.AwayTeam)
.有很多
.HasForeignKey(f=>f.AwayTeamId)
.WillCascadeOnDelete(假);
//其他三个FK也一样

我已禁用级联删除,因为默认情况下,它将为所需的关系启用。但是,由于您与
团队
表(以及
教练
表)有两个必需的关系,因此将导致从
夹具
团队
教练
的两个级联删除路径。SQL Server中禁止使用多个级联删除路径,因此您必须对
Fixture
Team
(以及
Fixture
Coach
之间)之间的两种关系中的至少一种禁用级联删除。

我尝试了这种方法并开始工作

主键表

public class TravelCity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CityId { get; set; }
    public string CityName { get; set; }
    public string CityDesc { get; set; }
    public string Status { get; set; }
}
具有外键的表

  public class TravelDetails
    {
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Int64 TravelId { get; set; }

    public Int32 FromLocation { get; set; }
    [ForeignKey("FromLocation"),InverseProperty("CityId")]
    public virtual TravelCity TravelCityFrom { get; set; }

    public Int32 ToLocation { get; set; }
    [ForeignKey("ToLocation"), InverseProperty("CityId")]
    public virtual TravelCity TravelCityTo { get; set; }


    public Int32 CurrentCity { get; set; }
    [ForeignKey("ToLocation"), InverseProperty("CityId")]
    public virtual TravelCity TravelCityCurrent{ get; set; }

}
这样试试吧,肯定行得通。。
干杯:)

我不认为对同一个表有多个FK引用有任何错误(例如,
团队
)-这完全可以。技术上没有问题。逻辑上可能是这样。我认为球队和教练是相关的,所以主队不能只有任何一个主教练。您可能希望对TeamCoach表(FK’s to Team and Coach)建模,并在
Fixture
中使用
TeamCoach
引用,而不是分别使用
Team
Coach
。团队和Coach是相关的,但团队的Coach可以更改,因此,使用TeamId获取教练并不总是可行的,因为此表将保存历史数据,其中一个团队可能会经历多个不同的教练。您可以有多个团队教练组合(即使有历史记录),并选择其中两个作为赛程。我可以想象你已经有了这样一张表,否则你将如何检查组合是否正确?感谢这篇伟大的文章,请查看我对原始文章的编辑。