Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate+同一列的多个外键_C#_Nhibernate_Fluent Nhibernate - Fatal编程技术网

C# NHibernate+同一列的多个外键

C# NHibernate+同一列的多个外键,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我正在尝试使用以下映射映射我的团队和Match表: //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> Matches { get; set

我正在尝试使用以下映射映射我的团队和Match表:

//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> Matches { get; set; }

    public Team()
    {
        Matches = 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.Matches)
            .Key(x => x.Columns.Add("Team1ID", "Team2ID"))
            .Inverse().Cascade.AllDeleteOrphan();

        Table("Teams");
    }
}
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 Team1 { get; set; }
    public virtual Team Team2 { 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.Team1, "Team1ID");
        References(x => x.Team2, "Team2ID");
        References(x => x.Cup, "CupID");
        Table("Matches");
    }
}
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");
    }
}
但是,它抛出一个异常,该异常表示:

外键 FKEFFCA4CA45169AED:匹配项[Team1ID, Team2ID]必须具有相同数量的 列作为引用的主键 团队[ID]

有什么建议吗

更新:

根据@Yads写的评论,我将一些东西混合在一起,从而解决了这个问题

我的代码:

//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> Matches { get; set; }

    public Team()
    {
        Matches = 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.Matches)
            .Key(x => x.Columns.Add("Team1ID", "Team2ID"))
            .Inverse().Cascade.AllDeleteOrphan();

        Table("Teams");
    }
}
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 Team1 { get; set; }
    public virtual Team Team2 { 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.Team1, "Team1ID");
        References(x => x.Team2, "Team2ID");
        References(x => x.Cup, "CupID");
        Table("Matches");
    }
}
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对我来说似乎有点恶心…

我不知道为什么,但我觉得我以前已经回答过这个问题了

您看到的错误发生是因为您正在基于复合反向键创建关联,而复合反向键将无法映射到单个外键

一种解决方案是尝试将理想的关系模型嵌入到对象模型中,或者,您可以丰富您的模型。我建议用一个丰富的模型来表达球队在比赛中的表现,你可以称之为参与。这将给你一个团队和比赛之间的多对多关系

这样做的缺点是,你需要将这种关系的重要性表达为商业规则,这样你就不能让三支球队在同一场比赛中打球

这样做的好处是,您可以在参与上有一个标志,表明获胜者是谁,这样您就不需要在对象模型上有WinnerId字段

您将得到如下使用的代码:

var match = new Match();
match.AddTeam(team1);
match.AddTeam(team2);

var winner = match.Participants.FindWinner();
winner = match.Winner; // alias for the above

看@jonnii-这正是我一开始就想到的方法然而,我发现球队和比赛之间存在多对多关系是错误的,因为我知道一场比赛总是只有两支球队。我用@Cade Roux=>讨论了这个问题,它更灵活,没有什么能阻止你在数据库中有三支球队参加比赛,但是这个模型更丰富、更具表现力。它还将简化您的查询,例如,想象一下查询今年已经打了3场比赛的球队。您建议的模型本身并不安全,需要验证,例如Team1和Team2不能相同,WinnerId需要是Team1Id或Team2Id中的一个。我宁愿接受基数痛苦,也不愿接受其他痛苦。@jonnii-我可以很容易地找到今年打了3场比赛的人:cupEntity.Teams.Wherex=>x.matches.Date==somedata;-也可以看到我更新的帖子。。。我知道如何在没有多对多的情况下让它工作,但是我没有完全意识到这样做的缺点。@ebb其实没有任何缺点,只是你的模型有点不稳定。我真的认为你应该考虑对协会进行建模。JONNI-但是这个协会将是相当无用的,因为我知道参加比赛的球队的确切数量。但你是对的,我的模型有点“不稳定”。。。