I'm trying to map my Team
and Match
table by using following mappings:
// 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");
}
}
// 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");
}
}
However, it throws an exception that says:
Foreign key (FKEFFCA4CA45169AED:Matches [Team1ID, Team2ID])) must have same number of columns as the referenced primary key (Teams [ID])
Any suggestions?
UPDATE:
I was able to solve it by mixing something together based on the comment wrote by @Yads.
My code:
// 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");
}
}
However, I'm not aware of what drawbacks this approach have... The .Concat() seems a bit nasty to me...
I don't know why, but I feel like I've answered this exact question before...
The error you're seeing is occurring because you're creating an association based upon a composite inverse key, which won't be able to be mapped to a single foreign key.
One solution would be to try to shoehorn your "ideal" relational model into your object model, or, alternatively you could enrich your model. I suggest having a rich model to express a team playing in a match, you could call it Participation
. This would give you a many to many relationship between teams and matches.
The downside to this is you would need to express the cardinality of the relationship as a business rule (so you can't have three teams playing in the same match).
The advantage is you could have a flag on the participation saying who the winner was, so that you don't need to have a WinnerId
field on your object model.
You'd end up with code that would be used like this:
var match = new Match();
match.AddTeam(team1);
match.AddTeam(team2);
var winner = match.Participants.FindWinner();
winner = match.Winner; // alias for the above
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.