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

C# 使用Linq获取与ID列表匹配的结果,c#,sql,asp.net,entity-framework,linq,C#,Sql,Asp.net,Entity Framework,Linq,我正在尝试获取满足a列表中包含的所有GenReid的GameID列表 部分表格如下: 编辑列表: 游戏id 所容纳之物 游戏类型游戏可以分为几种类型: 身份证件 游戏id 类型识别码 我需要获取游戏类型表中所有类型的游戏id的游戏id列表 例如: 流派id列表包括流派2和流派3 如果游戏Id=14存在于游戏类型表中,则类型Id=2和类型Id=3都存在。因此,它将包含在最终结果中 这是我的密码: // get the list of game_id's that have an editoria

我正在尝试获取满足a列表中包含的所有GenReid的GameID列表

部分表格如下:

编辑列表:

游戏id 所容纳之物 游戏类型游戏可以分为几种类型:

身份证件 游戏id 类型识别码 我需要获取游戏类型表中所有类型的游戏id的游戏id列表

例如:

流派id列表包括流派2和流派3

如果游戏Id=14存在于游戏类型表中,则类型Id=2和类型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
最终结果应该是游戏id的唯一列表,列表中的每个游戏都属于类型列表中列出的所有类型

我创建了几个步骤来帮助我理解查询,但它可能可以在一行中解决,我只是无法解决它

更新:这是我正在尝试的新代码

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

游戏和类型之间的关系是多对多的:一个游戏可以属于零个或多个类型,一个类型可以有零个或多个游戏

您需要属于游戏类型表中所有类型的所有游戏的ID

例如,如果您的列表游戏类型仅包含引用类型2和类型3的记录,则您需要属于类型2和类型3的所有游戏

请注意,可能存在不属于任何“游戏”的类型。在这种情况下,游戏类型表中没有与此类型相关的记录

下面是属性实体框架类的示例。类和属性的实际名称可能会有所不同,但您将获得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中包含所有usedGenres元素的每个游戏

要检查某个流派是否在Game.Tyres集合中,我们只需将Game.Tyres的流派ID与UsedGenReid的流派ID进行比较

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

游戏和类型之间的关系是多对多的:一个游戏可以属于零个或多个类型,一个类型可以有零个或多个游戏

您需要属于游戏类型表中所有类型的所有游戏的ID

例如,如果您的列表游戏类型仅包含引用类型2和类型3的记录,则您需要属于类型2和类型3的所有游戏

请注意,可能存在不属于任何“游戏”的类型。在这种情况下,游戏类型表中没有与此类型相关的记录

下面是属性实体框架类的示例。类和属性的实际名称可能会有所不同,但您将获得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中包含所有usedGenres元素的每个游戏

要检查某个流派是否在Game.Tyres集合中,我们只需将Game.Tyres的流派ID与UsedGenReid的流派ID进行比较

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

可以通过对表中的行进行分组来实现

使用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生成一个名为groupper game_id的记录。每个组的键是groupby子句中使用的game_id。每个组都是具有相同游戏id的行的集合,因此您可以将其视为任何其他数据库实体的集合,在这里您可以使用where语句和集合上的调用计数对其进行过滤。

您可以通过对表中的行进行分组来实现

使用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生成一个名为groupper game_id的记录。每个组的键是groupby子句中使用的game_id。每个组都是具有相同游戏id的行集合,因此您可以将其视为任何其他数据库实体集合,在这里,您可以使用where语句和集合上的调用计数对其进行过滤。

类似于以下内容:

        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();
从社论中选择游戏id,其中游戏id在游戏类型表中有一个包含所有不同类型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();
大概是这样的:

        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();
从社论中选择游戏id,其中游戏id在游戏类型表中有一个包含所有不同类型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();

这将是非常不有效的,因为游戏类型有所有同性恋者的类型,我只想要那些有编辑内容的人。这将是非常不有效的,因为游戏类型有所有同性恋者的类型,我只想要那些有编辑内容的人。有游戏应该遵守的类型列表的列表在哪里使用?我不明白你的问题中,你想要列表中所有类型的游戏,而不是列表中的所有游戏?如果列表中有游戏应该遵守的类型列表,那么该列表的用途在哪里?我不明白,在你的问题中,你想要什么 列表中包含所有类型的所有游戏-不是表中的所有游戏?