我正在尝试获取满足List<int>
中包含的所有genreIds的gameIds列表。
表格(部分):
editorial_list:
game_genres(游戏可以属于多种类型):
我需要获取game_genres表中所有genre_id
的游戏ID列表。
例如:
genre_id
的列表包括流派2和3。
如果game_genres
= 2和genre_id
= 3,genre_id
表中存在游戏ID = 14,那么它将包含在最终结果中。
这是我的代码:
// 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的唯一列表,列表中的每个游戏都属于所有类型中列出的类型{ {1}}。
我创建了几个步骤来帮助我理解查询,但它可以在一行中解决,我只是无法解决它。
更新:这是我尝试的新代码。
List<int>
答案 0 :(得分:2)
游戏和流派之间的关系是多对多的: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());
现在,您只需要Games
中属于每种类型的usedGenres
个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));
=每个游戏,其中usedGenres的每个元素都在Game.Genres集合中。
要检查类型是否在Game.Genres的集合中,我们只需将Game.Genres的GenreId与usedGenreIds的GenreId进行比较
var elmt = gridTestUtils.dataCell('grid1', <row>, <col>);
答案 1 :(得分:2)
这样的事情:
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_id在game_genre表中包含所有不同genre_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();
答案 2 :(得分:0)
你可以通过灌输表格中的行来实现它。
使用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();
这种灌注每game_id
产生一条记录(称为组)。每个组的Key
是&#34;组中使用的game_id
&#34;条款。每个组都是具有相同game_id
的行的集合,因此您可以将其视为任何其他数据库实体集合,在此处使用where
语句对其进行过滤,并在集合上调用Count()
。