我的查询应该计算包含给定流派的所有电影。
查询有效,但它查询数据库中每部电影的链接表,导致1分钟和6秒的加载时间。
表结构如下所示:
电影 包含所有电影
类型 包含所有类型的名称
MovieGenre 此表中的每条记录都包含电影ID和流派名称。
public async Task<int> CountMovies(List<string> pGenres)
{
return await (
from movie in Context.Movie
join genre in Context.MovieGenre on movie.MovieId equals genre.MovieId into genres
where pGenres.All(pGenre => genres.Any(genre => genre.GenreName == pGenre))
select movie
).CountAsync();
}
如何防止往返服务器并在数据库中执行所有操作?
上面的代码导致108次往返数据库,例如:
SELECT [genre0].[genre_name],[genre0].[movie_id]
FROM [Movie_Genre] AS [genre0]
WHERE 353 /* @_outer_MovieId */ = [genre0].[movie_id]
答案 0 :(得分:0)
首先将您的流派列表插入临时表,然后加入
答案 1 :(得分:0)
如果Context.MovieGenre
的类型为MovieGenres
,并且它包含单个MovieGenre
对象的集合,则添加扩展方法:
int CountMoviesWithGenre(this MovieGenres mg, List<string> genreNames)
{
return mg
.Where(mg=>genreNames.Contains(mg.GenreName,
StringComparison.InvariantCultureIgnoreCase))
.Select(m => m.MovieId)
.Distinct()
.Count();
}
这样称呼:
var genNames = new List<string> {"Horror", "Suspense","Action"};
var count = Context.MovieGenre.CountMoviesWithGenre(genNames);
答案 2 :(得分:0)
EF Core仍然存在将复杂查询转换为sql的一些问题,它将服务器执行与客户端执行混合在一起,并且查询中有一些内容正在客户端执行。而不是执行count(*)
正在加载所选电影的所有数据。要尝试改进查询,请尝试以下操作:
return await Context.MovieGenre.GroupBy(e=>e.MovieId,e=>e.GenreName)
.Where(g=>pGenres.All(pGenre => g.Contains(pGenre)))
.CountAsync();
主要问题是Where
条件,您还可以尝试以下操作:
return await Context.MovieGenre.Where(g=>pGenres.Contains(g.GenreName))
.GroupBy(e=>e.MovieId,e=>e.GenreName)
.Where(g=>pGenres.Count==g.Count())
.CountAsync();
答案 3 :(得分:0)
我已经完成了。
public async Task<int> CountMovies(List<string> pGenres, int? year, decimal? minPrice,
decimal? maxPrice)
{
using (var command = Context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = $"SELECT COUNT(DISTINCT Movie.movie_id) from Movie_Genre join Movie on Movie.movie_id = Movie_Genre.movie_id where genre_name in ('Action', 'Adult')";
Context.Database.OpenConnection();
using (var result = command.ExecuteReader())
{
await result.ReadAsync();
int amount = result.GetInt32(0);
Context.Database.CloseConnection();
return amount;
}
}
}
答案 4 :(得分:0)
我最近看过/使用的一个很好的技巧是你可以告诉你很多:
public async Task<int> CountMovies(List<string> pGenres) {
return await (
from movie in Context.Movie
join genre in Context.MovieGenre on movie.MovieId equals genre.MovieId into genres
where genres.Where(genre => pGenres.Contains(genre.GenreName)).Count() == pGenres.Count()
select movie
).CountAsync();
}
答案 5 :(得分:-1)
这是一次旅行,并返回至少包含一个pGeners的所有电影。
var moviesCount = Context.MovieGenre
.Where(x => pGenres.Contains(x.GenreName))
.Select(x => x.Movie).Distinct().ToList().Count();