我在Entity Framework Core中有一个类似这样的模型:
public class Anime
{
public int EpisodeCount { get { return Episodes.Count() } }
public virtual ICollection<Episode> Episodes { get; set; }
}
我的EpisodeCount问题是0
。目前的解决方案是在我的EF查询中运行.Include(x => x.Episodes)
,但是会加载不需要的整个剧集集合。这也增加了我的HTTP请求时间,从100毫秒到700毫秒,这是不好的。
我不愿意为简单的细节牺牲时间,所以有没有一个解决方案,我可以让EF只查询剧集的COUNT,而不加载整个集合?
我被建议这样做
var animeList = context.Anime.ToPagedList(1, 20);
animeList.ForEach(x => x.EpisodeCount = x.Episodes.Count());
return Json(animeList);
但这也会在EpisodeCount中返回0
,因此它不是一个可行的解决方案。
答案 0 :(得分:2)
您需要将所需数据投影到特殊类(例如,View.Model,DTO等)。不幸的是(或不是?),为了避免N + 1个查询,投影不仅要包括计数,还要包括所有其他字段。
例如:
型号:
public class Anime
{
public int Id { get; set; }
public string Name { get; set; }
// other properties...
public virtual ICollection<Episode> Episodes { get; set; }
}
ViewModel / DTO:
public class AnimeInfo
{
public int Id { get; set; }
public string Name { get; set; }
// other properties...
public int EpisodeCount { get; set; }
}
然后是以下代码:
var animeList = db.Anime.Select(a => new AnimeInfo
{
Id = a.Id,
Name = a.Name,
EpisodeCount = a.Episodes.Count()
})
.ToList();
生成以下单个SQL查询:
SELECT [a].[Id], [a].[Name], (
SELECT COUNT(*)
FROM [Episode] AS [e]
WHERE [a].[Id] = [e].[AnimeId]
) AS [EpisodeCount]
FROM [Anime] AS [a]