bin*_*bin 6 c# entity-framework entity-framework-core asp.net-core
我在 Entity Framework Core 中有一个模型,它是这样的:
public class Anime
{
public int EpisodeCount { get { return Episodes.Count() } }
public virtual ICollection<Episode> Episodes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我遇到了 EpisodeCount 的问题0。目前的解决方案是.Include(x => x.Episodes)在我的 EF 查询中运行 a ,但这会加载不需要它的整个剧集集合。这也增加了我的 HTTP 请求时间,从 100 毫秒到 700 毫秒,这并不好。
我不愿意为简单的细节牺牲时间,那么有没有一种解决方案可以让 EF 只查询剧集的 COUNT,而不加载整个集合?
我被建议这样做
var animeList = context.Anime.ToPagedList(1, 20);
animeList.ForEach(x => x.EpisodeCount = x.Episodes.Count());
return Json(animeList);
Run Code Online (Sandbox Code Playgroud)
但这也会0在 EpisodeCount 中返回,因此这不是一个可行的解决方案。
您需要将所需的数据投影到一个特殊的类(又名 ViewModel、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; }
}
Run Code Online (Sandbox Code Playgroud)
视图模型/DTO:
public class AnimeInfo
{
public int Id { get; set; }
public string Name { get; set; }
// other properties...
public int EpisodeCount { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后如下代码:
var animeList = db.Anime.Select(a => new AnimeInfo
{
Id = a.Id,
Name = a.Name,
EpisodeCount = a.Episodes.Count()
})
.ToList();
Run Code Online (Sandbox Code Playgroud)
生成以下单个 SQL 查询:
SELECT [a].[Id], [a].[Name], (
SELECT COUNT(*)
FROM [Episode] AS [e]
WHERE [a].[Id] = [e].[AnimeId]
) AS [EpisodeCount]
FROM [Anime] AS [a]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3042 次 |
| 最近记录: |