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

发布于 2024-10-20 17:19:40 字数 2377 浏览 2 评论 0原文

我有 2 个表,分别名为 TeamsMatches - 我希望能够添加一个由 2 个团队组成的 Match,但也能够获取特定团队的所有比赛。

我能做的是:

  • A) 建立多对多关系 在团队比赛之间 表

  • B) 在表中添加两列 匹配 名为 HomeTeam 的表以及 AwayTeam 这是外键 指的是Teams中的一个Team 表。

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

现在,当需要在我的实体中声明此关系时,我需要与 Match 实体建立 2 个多对一关系,因为 Match 实体具有2 个引用 Team 的外键 - 并且 MatchTeam 中的外键/引用数量必须相同,然后我最终会得到这样的结果:

// Team.cs

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

// Match.cs

public class Match
{
    public virtual int ID { get; private set; } 
    public virtual Team HomeTeam { get; set; } 
    public virtual Team AwayTeam { get; set; } 
    public virtual int WinnerID { get; set; } 
    public virtual Cup Cup { get; set; }
}

public class MatchMap : ClassMap<Match>
{
    public MatchMap()
    {
        Id(x => x.ID); 
        Map(x => x.WinnerID); 
        References(x => x.HomeTeam, "HomeTeamID"); 
        References(x => x.AwayTeam, "AwayTeamID"); 
        References(x => x.Cup, "CupID"); 

        Table("Matches");
    }
}

如代码所示,然后我必须使用 .Concat() 来合并 HomeMatches 和 AwayMatches一个团队,获得特定团队的所有比赛..

这真的是最好的方法吗?

I'm having 2 tables, named Teams and Matches - I want to be able to add a Match which consist of 2 Teams, but also be able to get all the Matches for a specific Team.

What I can do is:

  • A) Make a Many-to-Many relationship
    between the Teams and Matches
    table

  • B) Make two extra columns in the
    Matches table named HomeTeam and
    AwayTeam which is foreign keys that
    refers to a Team in the Teams
    table.

We all agree on that B sounds best, since I know the exact amount of teams that will participate in a match everytime - right?

Now when it comes to declare this relationship in my entities, then I'll need to have 2 Many-to-one relationships to the Match entity, since the Match entity have 2 foreign keys that refers to a Team - and sine the number of foreign keys / references must be the same from both Match and Team, then I'll end up with something like this:

// Team.cs

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

// Match.cs

public class Match
{
    public virtual int ID { get; private set; } 
    public virtual Team HomeTeam { get; set; } 
    public virtual Team AwayTeam { get; set; } 
    public virtual int WinnerID { get; set; } 
    public virtual Cup Cup { get; set; }
}

public class MatchMap : ClassMap<Match>
{
    public MatchMap()
    {
        Id(x => x.ID); 
        Map(x => x.WinnerID); 
        References(x => x.HomeTeam, "HomeTeamID"); 
        References(x => x.AwayTeam, "AwayTeamID"); 
        References(x => x.Cup, "CupID"); 

        Table("Matches");
    }
}

As the code shows, then I'll have to use .Concat() to merge the HomeMatches and AwayMatches for a team, to get all the matches for a specific team..

Is this really the best way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

々眼睛长脚气 2024-10-27 17:19:40

B 是最好的选择,因为 A 有点转移注意力。您确实不希望比赛和球队之间存在多对多表,但您不希望它们的原因不是因为您知道参加比赛的球队数量,而是因为比赛实际上是多对多团队与团队之间的关系已经存在。

碰巧的是,在这种情况下,当两个团队之间存在多对多关系时,您可以将其称为匹配,并且它具有自己的一组属性(时间、日期、地点...)。

比赛肯定应该有两个外键来组队,因为比赛是你的多对多表。

B is the best way to go because A is a bit of a red herring. You don't really want a many to many table between Matches and Teams but the reason you don't want them is not because you know the number of teams that will be in a match, but because a match is actually a many to many relationship already for team to team.

It just happens that in this case when you have a many to many relationship between two teams you call it a match and it has it's own set of properties (time, date, location...).

Match should definitely have two foreign keys to team as match is your many to many table.

南…巷孤猫 2024-10-27 17:19:40

在关系模型中,它看起来像这样。因此,两个外键就可以了,HomeTeamIDAwayTeamID 就是所谓的角色名称

在此处输入图像描述

In a relational model it would look something like this. So two foreign keys is fine, the HomeTeamID and AwayTeamID are so called role names.

enter image description here

稚然 2024-10-27 17:19:40

事实上,这可能是最好的方法。我认为您只是遇到了一个问题,即您需要将两个列表连接在一起才能提取看似简单的查询。然而,您使用的结构不仅仅是将两个团队联系起来,它还提供了一个几乎分层的结构,即 HomeTeam = Parent,AwayTeam = Child。

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

[Team]

[MatchTeam]
TeamID
MatchID
IsHomeTeam

[Match]

This may in fact be the best way to go. I think you are just having a problem with the fact that you need to join two lists together to pull what seems to be a simple query. However, the structure you are using isn't just relating the two teams, it is providing an almost-hierarchical structure, i.e. HomeTeam = Parent, AwayTeam = Child.

If you want to simply relate the two, you can create the Many-To-Many like you said:

[Team]

[MatchTeam]
TeamID
MatchID
IsHomeTeam

[Match]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文