同一主键表的多个外键

时间:2012-11-11 07:25:32

标签: 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)

使用FixtureId的外键将这些数据分成两个表HomeTeam和AwayTeam会更好吗?这是当前由实体框架生成的内容:

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

2 个答案:

答案 0 :(得分:10)

显然,EF不会将int属性AwayTeamId检测为AwayTeam等导航属性的外键,因为Team中的主键属性不是Id {1}}但是TeamId。如果它们的名称类似于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

我已禁用级联删除,因为默认情况下会为所需关系启用它。但是因为你有Team表(以及Coach表)的两个必需关系,它将导致从FixtureTeam和{{}的两个级联删除路径1}}。 SQL Server中禁止多个级联删除路径,因此必须对CoachFixture之间(以及TeamFixture之间的两个关系中的至少一个禁用级联删除)。

答案 1 :(得分:1)

我试过这种方式&amp;工作

主键表

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

}

尝试这种方式它会勉强工作.. 干杯:)