首先,抱歉,如果此问题的名称不够具有描述性。我不确定该怎么命名。我有两张桌子,
Games
int GameId,
int HomeTeamId,
string HomeTeamName,
int HomeTeamScore,
int AwayTeamId,
int AwayTeamScore,
string AwayTeamName
和
PlayersInGame
int GameId,
int PlayerId,
string PlayerName,
string TeamName,
int TeamId
我想要做的是查询这两个表,结果如下
ViewModel
string PlayerName,
string Teams,
int GameCount,
int NumberOfWins
我的问题是我多年来一直在查询游戏,因此玩家可以为多个团队效力,在这种情况下我希望它看起来像这样
Team1/Team2/...
团队名称以/
分隔。
另一个问题是,我想获得玩家参与的游戏总数,但也想出他的胜利记录。找出他的胜利记录的唯一方法是将HomeTeamScore与AwayTeamScore进行比较,并检查玩家的TeamId与获胜的团队ID。
我想知道这里最好的方法是什么?我怀疑用一个查询有办法做到这一点吗?
答案 0 :(得分:2)
我假设(通过查看PlayerId
)你还有一个你没有指定的Player
类/表。
让我们从让所有玩家开始:
IEnumerable<Player> players = _db.Players;
我们需要将每位玩家映射到ViewModel
,因此我们将使用Select:
IEnumerable<ViewModel> models = players.Select(p => new ViewModel());
但是这些ViewModel
个实例只是空的,我们需要填写适当的数据,让我们从最简单的数据开始,即玩家的名字:
IEnumerable<ViewModel> models = players.Select(p => new ViewModel()
{
PlayerName = p.PlayerName
});
接下来,我们需要获取玩家参与的所有团队。为此,我们将查询PlayersInGame
表并使用Where按玩家的ID过滤掉。我们还会将每个结果映射到TeamName
并对其进行格式化。
IEnumerable<ViewModel> models = players.Select(p => new ViewModel()
{
PlayerName = p.PlayerName,
Teams = String.Join("/", _db.PlayersInGame.Where(pg => pg.PlayerId == p.PlayerId).Select(pg => pg.TeamName))
});
现在我们需要计算游戏数量,我们将再次阅读PlayersInGame
,但现在我们将使用Count方法:
IEnumerable<ViewModel> models = players.Select(p => new ViewModel()
{
PlayerName = p.Name,
Teams = String.Join("/", _db.PlayersInGame.Where(pg => pg.PlayerId == p.Id).Select(pg => pg.TeamName)),
GameCount = _db.PlayersInGame.Count(pg => pg.PlayerId == p.Id)
});
现在,在最后一部分,我们需要计算玩家赢了多少次,所以我们只需要查询玩家的游戏然后计算他/她赢了多少。最棘手的部分可能是确定球员是在主队还是客队。
IEnumerable<ViewModel> models = players.Select(p => new ViewModel()
{
PlayerName = p.PlayerName,
Teams = String.Join("/", _db.PlayersInGame.Where(pg => pg.PlayerId == p.PlayerId).Select(pg => pg.TeamName)),
GameCount = _db.PlayersInGame.Count(pg => pg.PlayerId == p.PlayerId),
NumberOfWins = _db.PlayersInGame.Where(pg => pg.PlayerId == p.PlayerId).Count(pg =>
{
Game g = _db.Games.Single(g => g.GameId == pg.GameId);
bool isHome = g.HomeTeamId == pg.TeamId;
return isHome ? (g.HomeTeamScore > g.AwayTeamScore) : (g.AwayTeamScore > g.HomeTeamScore);
})
});
最终结果:
IEnumerable<ViewModel> models = _db.Players.Select(p => new ViewModel()
{
PlayerName = p.PlayerName,
Teams = String.Join("/", _db.PlayersInGame.Where(pg => pg.PlayerId == p.PlayerId).Select(pg => pg.TeamName)),
GameCount = _db.PlayersInGame.Count(pg => pg.PlayerId == p.PlayerId),
NumberOfWins = _db.PlayersInGame.Where(pg => pg.PlayerId == p.PlayerId).Count(pg =>
{
Game game = _db.Games.Single(g => g.GameId == pg.GameId);
bool isHome = game.HomeTeamId == pg.TeamId;
return isHome ? (game.HomeTeamScore > game.AwayTeamScore) : (game.AwayTeamScore > game.HomeTeamScore);
})
});
答案 1 :(得分:0)
它非常复杂,试着参考这篇文章。因此,在Teams
,GameCount
和NumberOfWin
字段中,我再次执行查询以获取每个值并将其放入变量结果中,然后您可以将其分配给ViewModel类
var players = new List<PlayersInGame>
{
new PlayersInGame
{
PlayerId = 1,
GameId = 1,
PlayerName = "Manu Ginobili",
TeamId = 1,
TeamName = "Spurs"
},
new PlayersInGame
{
PlayerId = 3,
GameId = 1,
PlayerName = "Michael Jordan",
TeamId = 1,
TeamName = "Spurs"
},
new PlayersInGame
{
PlayerId = 3,
GameId = 2,
PlayerName = "Michael Jordan",
TeamId = 3,
TeamName = "Bulls"
},
new PlayersInGame
{
PlayerId = 2,
GameId = 1,
PlayerName = "James Harden",
TeamId = 2,
TeamName = "Rockets"
}
};
var games = new List<Games>
{
new Games
{
GameId = 1,
AwayTeamId = 2,
AwayTeamName = "Rockets",
AwayTeamScore = 107,
HomeTeamId = 1,
HomeTeamName = "Spurs",
HomeTeamScore = 110
},
new Games
{
GameId = 2,
AwayTeamId = 2,
AwayTeamName = "Rockets",
AwayTeamScore = 107,
HomeTeamId = 3,
HomeTeamName = "Bulls",
HomeTeamScore = 110
}
};
/*
string PlayerName,
string Teams,
int GameCount,
int NumberOfWins*/
var result = (from g in games
join p in players on g.GameId equals p.GameId
select new
{
PlayerNAme = p.PlayerName,
Teams = string.Join(",", players.Where(x => x.PlayerName == p.PlayerName).Select( m=> new { m.TeamName })),
GameCount = players.Count(x => x.PlayerName == p.PlayerName),
NumberOfWins = games.Count(m => ((players.Where(x => x.PlayerName == p.PlayerName).Select(x => x.TeamId)).Contains(m.AwayTeamId) && m.AwayTeamScore > m.HomeTeamScore) || ((players.Where(x => x.PlayerName == p.PlayerName).Select(x => x.TeamId)).Contains(m.HomeTeamId) && m.HomeTeamScore > m.AwayTeamScore))
}
).Distinct();