2017-05-11 21 views
0

まず、この問題の名前が十分に説明できない場合は、ごめんなさい。私はそれに何を命名するか分からなかった。私は私が何をしたいのか2つのテーブル複合LINQクエリの複雑なwhere句

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 

その結果、これらの2つのテーブルを照会しています何年も前からプレイヤーが複数のチームでプレーしていた場合、このように表示したい場合は

Team1/Team2/... 

チーム名は/で区切られています。 もう1つの問題は、プレイヤーが参加したゲームの総数を取得したいだけでなく、勝利記録を把握したいということです。彼の勝利記録を把握する唯一の方法は、HomeTeamScoreとAwayTeamScoreを比較し、PlayerのTeamIdに勝ったチームIDを確認することです。

ここで最善のアプローチは何ですか?私は単一のクエリでこれを行う方法があるのだろうか?

答えて

2

あなたは指定しなかったPlayerクラス/テーブルを持っているとします(PlayerIdを見て)。

は、すべてのプレイヤーを取得することにより開始するのをしてみましょう:

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

、それは非常に複雑であり、この記事を参照してみてください。だから、フィールドTeamsGameCountで、かつ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(); 

enter image description here