2017-06-15 34 views
0

我想要獲得滿足所有genreIds包含在List<int>中的gameIds列表。使用Linq獲取匹配ID列表的結果

的表(部分):

editorial_list:

  • game_id
  • 內容

game_genres(遊戲可以屬於多個流派):

  • ID
  • game_id
  • genre_id

我需要存在在game_genres表中的所有genre_id的遊戲的遊戲ID的列表。

例如:

genre_id列表的包括類型2和3

如果遊戲ID = 14存在於game_genres表兩者genre_id = 2和genre_id = 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 

最終結果應該game_id的獨特的列表,在列表每場比賽屬於所有這是在體裁List<int>列出的流派。

我創建了幾個步驟來幫助我理解查詢,但它可能能夠在一行中解決,我只是無法解決它。

更新:這是我嘗試的新代碼。

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可以屬於零個或多個流派和Genre可以有零個或更多的遊戲。

你想要game-genres表中所有屬於所有流派的遊戲(的ID)。

例如,如果你的列表的遊戲類型包含引用只記錄流派2和流派3,那麼你要屬於類型2和3

注意,一個Genre可能存在的所有比賽,是不是擁有任何'遊戲'。在這種情況下,遊戲類型表中沒有關於此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表。另一方面:如果你的遊戲類型表中有一個元素,那麼至少有一個屬於該類型的遊戲。

所以,你不希望所有類型,您只需要由至少一個Game使用流派。

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

現在你想只有那些屬於每一個流派在usedGenres Games =每場比賽,其中usedGenres的所有元素都在收集Game.Genres。

要檢查一個流派是Game.Genres的集合中,我們只需要在GenreId與usedGenreIds的GenreId比較Game.Genres的

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

您可以通過從groupping行實現它你表。

使用Lambda表達式:

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

因爲game_genres有流派的所有GAEMS這將是非常不見效,我只是希望那些誰有編輯內容。 –

1

事情是這樣的:

 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_GENRE表中的所有不同genre_ids進入選擇game_id。

如果你想有一個列表,而不是所有表中的所有流派的遊戲:

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

在哪裏使用具有該遊戲應該遵守,以 –

+0

阿餘did't明白你的問題,你想有所有類型列表中的所有遊戲類型的列表清單的 - 不是所有的表? –

+0

現在看看編輯的答案。 –

相關問題