2017-06-15 6 views
0

私はList<int>に含まれるすべてのgenreIdsを満たすgameIdのリストを取得しようとしています。Linqを使ってIDのリストと一致する結果を取得

テーブル(部分):

editorial_list:

  • game_id
  • コンテンツ

game_genres(ゲームはいくつかのジャンルに属することができます):

  • ID
  • game_id
  • は、私がgame_genresテーブル内のすべてのgenre_id年代のために存在するゲームのゲームIDのリストを取得する必要があり

をgenre_id。例えば

:ゲームIdは= 14 = 2 genre_idと= 3 genre_idの両方のためにgame_genresテーブルに存在する場合

genre_id年代のリストは、それがそうジャンル2及び3

を含み最終結果に含まれます。ここで

が私のコードです:

// get the list of game_id's that have an editorial 
var editorialList = (from ee in db.editorials where ee.is_enabled == true select new { 
    game_id = ee.game_id 
}).ToList(); 

// Produce a list of the games in the editorials and their genre Ids that the belong to 
var gameAndGenres = (from el in editorialList join gg in db.game_genres 
    on el.game_id equals gg.game_id 

    select new { 
     game_id = el.game_id, 
      genre_id = gg.genre_id 
    } 
); 

var res = gameAndGenres.Where(
    x => x.genres.Contains(x.genre_id)) == genres.Count; // stuck here 

エンドはがリスト内の各ゲームはジャンルList<int>にリストされたすべてののジャンルに属していることを、game_idの独特のリストでなければなりません結果。

クエリを理解するのに役立ついくつかの手順を作成しましたが、1行で解決できる可能性があり、解決できませんでした。

更新:これは私が試みている新しいコードです。 Gameがゼロ以上のジャンルに属することができますし、Genreがゼロ以上のゲームを持つことができます。

var res = gameAndGenres.GroupBy(x => x.game_id) 
    .Select(g => new { 
    game_id = g.Key, 
    genreIds = g.Select(c => c.genre_id) 

    }); 

    var res2 = res.Where(x => genres.Intersect(x.genreIds).Count() 
    == genres.Count()).ToList(); 

答えて

1

ゲームとジャンルとの関係は、多対多です。

あなたのgame-genresテーブルのすべてのジャンルに属するすべてのゲームが(IDの)欲しいです。例えば

、あなたのリストのゲームジャンルは2、ジャンル3をジャンルに参照を持つレコードだけが含まれている場合、あなたはGenreがそれを存在し得ることはジャンルに属しているすべてのゲームは、2と3

注意ではありませんしたいです任意の「ゲーム」によって所有されています。この場合、ゲームジャンルテーブルには、Genreを参照するレコードはありません。

以下は、Property Entity Frameworkクラスの例です。クラスおよびプロパティの実際の名前は変更される場合がありますが、あなたは、IDに取得します

public class Game 
{ 
    public int GameId {get; set;} 
    public virtual ICollection<Genre> Genres {get; set;} 
    ... // other properties 
} 
public class Genre 
{ 
    public int GenreId {get; set; 
    public virtual ICollection<Game> Games {get; set;} 
    ... 
} 
public MyDbContext : DbContext 
{ 
    public DbSet<Game> Games {get; set;} 
    public DbSet<Genre> Genres {get; set;} 
    ... 
} 

エンティティフレームワークモデルビルダーがゲームとジャンル間の多対多の関係があることを検出し、自動的に追加されますあなたの「ゲームジャンル」のようなテーブル。

素晴らしいことは、あるジャンルがどのゲームにも属していない場合、それはあなたのgame_genresテーブルには含まれません。あなたのゲームジャンルテーブルに要素がある場合、そのジャンルに属するゲームが少なくとも1つはあります。

すべてのジャンルが欲しいわけではないので、少なくとも1つのジャンルで使用されているジャンルがほしいだけですGame

IEnumerable<Genre> usedGenres = dbContext.Genres 
    .Where(genre => genre.Games.Any()); 

は今、あなたが欲しいだけusedGenres にあらゆるジャンルに属するGames = usedGenresのすべての要素は、収集Game.Genresにあるすべてのゲーム。ジャンルはGame.Genresのコレクションである場合、我々は唯一のあなたは、あなたから行をgrouppingことによってそれを達成することができますusedGenreIds

IEnumerable<int> usedGenreIds = usedGenres 
    .Select(genre => genre.GenreId); 
IEnumerable<Game> gamesWithAllUsedGenres = dbContext.Games 
    .Where(game => usedGenreIds.All(genreId => game.Genres.Select(genre => genre.GenreIdContains(genreId)); 
0

のGenreIdでGame.GenresのGenreIdを比較する必要がチェックするには

テーブル。ラムダ式を使用

var res = db.game_genres.GroupBy(gg => gg.game_id) 
    .Where(g => g.Count() == db.genres.Count()) 
    .Select(x => x.Key).ToList(); 

またはLINQを使用して:

var res = (from gg in db.game_genres 
      group gg by gg.game_id into g 
      where g.Count() == db.genres.Count() 
      select g.Key).ToList(); 

ようなgrouppingはgame_idごと(グループと呼ばれる)のレコードを生成します。各グループのKeyは、 "group by"句で使用されるgame_idです。各グループは、game_idという等しい行のコレクションです。したがって、他のデータベースエンティティのコレクションと同様に扱うことができます。ここでは、whereステートメントを使用してフィルタリングし、Count()をコールします。このような

+0

これは非常に効果的ではないだろう、私はちょうど人々が欲しいです編集内容があります。 –

1

何か:game_idはgame_genreテーブル内のすべての個別genre_idsのエントリを持っているの社説から

 var gamesIds = db.editorials 
      .Where(e => db.game_genres.Select(gg => gg.genre_id).Distinct().All(genId => db.game_genres.Any(gg => gg.game_id == e.game_id && gg.genre_id == genId))) 
      .Select(e => e.game_id) 
      .ToList(); 

選択game_id。

あなたの代わりに、テーブル内のすべてのリスト内のすべてのジャンルを持つすべてのゲームしたい場合:game_genresはすべてgaemsためのジャンルを持っているので

List<int> genreIds = new List<int>() {1,2,3}; 

    var gamesIds = db.editorials 
     .Where(e => genreIds.All(genId => db.game_genres.Any(gg => gg.game_id == e.game_id && gg.genre_id == genId))) 
     .Select(e => e.game_id) 
     .ToList(); 
+0

List の使用場所は、ゲームが準拠しなければならないジャンルのリストがあります。 –

+0

ああ、あなたの質問では、すべてのジャンルがリストに入っているすべてのゲームがほしいと思っています? –

+0

編集された答えを見てください。 –

関連する問題