c# - 使用 Linq 获取与 ID 列表匹配的结果

标签 c# sql asp.net entity-framework linq

我正在尝试获取满足 List<int> 中包含的所有 genreId 的 gameId 列表.

表格(部分):

编辑列表:

  • 游戏编号
  • 内容

game_genres(游戏可以属于几种类型):

  • 编号
  • 游戏编号
  • 流派编号

我需要获取所有 genre_id 存在的游戏的游戏 ID 列表。在 game_genres 表中。

例如:

列表genre_id的包括类型 2 和类型 3。

如果 Game Id = 14 存在于 game_genres 中两者的 table 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();

最佳答案

Game 和 Genre 之间的关系是多对多的:一个 Game 可以属于零个或多个 genre,一个 Genre 可以有零个或多个 Games。

您需要在您的 game-genres 表中属于所有流派的所有游戏(的 ID)。

例如,如果您的游戏流派列表仅包含引用流派 2 和流派 3 的记录,那么您需要属于流派 2 和流派 3 的所有游戏。

请注意,可能存在不属于任何“游戏”的类型。在那种情况下,游戏流派表中没有记录引用此 Genre

下面是您的属性 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;}
    ...
}

Entity Framework 模型构建器会检测到 Games 和 Genres 之间存在多对多关系,并会自动添加一个类似于“游戏流派”的表。

好处是,如果某个类型不属于任何游戏,它就不会出现在您的 game_genres 表中。反之亦然:如果您的游戏类型表中有一个元素,那么至少有一款游戏属于该类型。

所以您不需要所有类型,您只需要至少被一个游戏使用的类型。

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

现在您只需要属于 usedGenres 中每个类型的那些游戏 = usedGenres 的每个元素都在集合 Game.Genres 中的每个游戏。

要检查一个流派是否在 Game.Genres 集合中,我们只需要比较 Game.Genres 的 GenreId 和 usedGenreIds 的 GenreId

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

关于c# - 使用 Linq 获取与 ID 列表匹配的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44566175/

相关文章:

CodeRunner 2 中的 C# 汇编

sql - 删除唯一约束时遇到问题

javascript - 通过Request.Form传递二维数组(或对象数组)?

asp.net - 如何使用 EF 在开发数据库和实时数据库之间切换?

asp.net - 直接将 .aspx 转换为 .pdf

c# - System.Collections.Generic.List 中的某项在什么情况下不会被删除成功?

c# - 在 Windows 10 全屏中使用 CameraCaptureUI

c# - 如何使只读结构 XML 可序列化?

sql - 如何将查询答案传递给限制函数 Impala

java - 生成唯一的客户 ID/在配置单元中插入唯一的行