先上代码
part 1:实体类(主外键已关联)
public class Movie { public int Id { get; set; } public string Name { get; set; } public virtual List<MovieGenres> MovieGenres { get; set; } } public class Genre { public int Id { get; set; } public string Name { get; set; } } public class MovieGenres { public int Id { get; set; } public int MovieId { get; set; } public int GenreId { get; set; } public virtual List<Movie> Movies { get; set; } public virtual List<Genre> Genres{ get; set; } }
part 2:查询
//已知 某影片类别分别为1,2,3 var genres = new int[]{ 1,2,3 }; //查询出(类别)相似度最匹配的2个 var movies = await _context.MovieGenres.Include(m => m.Genre) .Where(m => genres.Contains(m.GenreId)) .GroupBy(m=>m.MovieId) .OrderByDescending(g=>g.Count()) .Take(2) .ToListAsync();
查出的数据是正确的,但是生成的SQL语句居然是
SELECT [m0].[Id], [m0].[GenreId], [m0].[MovieId] FROM [MovieGenres] AS [m0] WHERE [m0].[GenreId] IN (1, 2, 3) ORDER BY [m0].[MovieId]
显然不是我想要的,这样写会把所有数据全部加载到内存再筛选出我要的结果。
其实我还想连Movie表查出Name信息,不知道怎么写,所以是分成两段来写,第一段表达式查出所有匹配的MovieId,第二段查出Movie信息。
用原生SQL一句就解决的问题,各位大神看看怎么写?用LINQ和表达式树写都行,伪代码也行。
MovieGenres实体修正一下,
public virtual Movie Movie { get; set; }
public virtual Genre Genre{ get; set; }
EF Core 2.0 的 GroupBy
就是这样的,使用 EF Core 2.1 才能解决这个问题,但 EF Core 2.1 目前处于 Preview 1 ,详见 Announcing Entity Framework Core 2.1 Preview 1:
Before version 2.1, in EF Core the GroupBy LINQ operator was always be evaluated in memory. We now support translating it to the SQL GROUP BY clause in most common cases.