架构 - 同一主键的2个外键?

时间:2011-03-08 11:12:13

标签: sql database nhibernate database-design architecture

我有2个名为TeamsMatches的表 - 我希望能够添加一个由{2}组成的Match,但也能够获得所有匹配特定Team

我能做的是:

  • A)建立多对多的关系 在TeamsMatches之间 表

  • B)在中添加两个额外的列 名为Matches的{​​{1}}表 HomeTeam这是外键 是指AwayTeam中的一个团队 表

我们都同意 B 听起来最好,因为我知道每次参加比赛的球队的确切数量 - 对吗?

现在,当我要在我的实体中声明这种关系时,我需要与Teams实体建立2个多对一关系,因为Match实体有2个外键引用Match - 并且正确的{/ 1}}和Team的外键/引用数必须相同,那么我最终会得到这样的结果:

// Team.cs

Match

// Match.cs

Team

如代码所示,那么我将不得不使用public class Team { public virtual int ID { get; private set; } public virtual string TeamName { get; set; } public virtual Cup Cup { get; set; } public virtual IList<Match> HomeMatches { get; set; } public virtual IList<Match> AwayMatches { get; set; } public virtual IList<Match> Matches { get { return HomeMatches.Concat(AwayMatches).ToList(); } } public Team() { HomeMatches = new List<Match>(); AwayMatches = new List<Match>(); } } public class TeamMap : ClassMap<Team> { public TeamMap() { Id(x => x.ID); Map(x => x.TeamName).Not.Nullable(); References(x => x.Cup, "CupID"); HasMany(x => x.HomeMatches).KeyColumn("HomeTeamID").Inverse().Cascade.AllDeleteOrphan(); HasMany(x => x.AwayMatches).KeyColumn("AwayTeamID").Inverse().Cascade.AllDeleteOrphan(); Table("Teams"); } } 合并一个团队的HomeMatches和AwayMatches,以获得特定团队的所有匹配。

这真的是最好的方式吗?

3 个答案:

答案 0 :(得分:3)

B是最好的方式,因为A有点红鲱鱼。你真的不想在比赛和球队之间有多对多的桌子,但是你不想要他们的原因不是因为你知道将在比赛中的球队数量,而是因为比赛实际上是多对多的已经为团队与团队建立了关系。

恰巧在这种情况下,当你在两个团队之间有多对多的关系时,你称之为匹配,并且它拥有自己的一组属性(时间,日期,位置......)。

匹配肯定会有两个外键给团队,因为匹配是你的多对多表。

答案 1 :(得分:2)

在关系模型中,它看起来像这样。所以两个外键很好,HomeTeamIDAwayTeamID被称为角色名称

enter image description here

答案 2 :(得分:1)

这实际上可能是最好的方式。我认为你只是遇到一个问题,你需要将两个列表连接在一起以拉出似乎是一个简单的查询。但是,您使用的结构不仅仅与两个团队相关,它提供了几乎分层的结构,即HomeTeam = Parent,AwayTeam = Child。

如果你想简单地将两者联系起来,你可以像你说的那样创建多对多:

[Team]

[MatchTeam]
TeamID
MatchID
IsHomeTeam

[Match]