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获取教练并不总是可行的,因为此表将保存历史数据,其中一个团队可能会经历多个不同的教练。您可以有多个团队教练组合(即使有历史记录),并选择其中两个作为赛程。我可以想象你已经有了这样一张表,否则你将如何检查组合是否正确?感谢这篇伟大的文章,请查看我对原始文章的编辑。