我有一个包含多个字段的表,这些字段是另一个表中主键的外键。例如:
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; }
}
答案 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
表)的两个必需关系,它将导致从Fixture
到Team
和{{}的两个级联删除路径1}}。 SQL Server中禁止多个级联删除路径,因此必须对Coach
和Fixture
之间(以及Team
和Fixture
之间的两个关系中的至少一个禁用级联删除)。
答案 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; }
}
尝试这种方式它会勉强工作.. 干杯:)