Optimize post categories, tags usage counting

This commit is contained in:
2025-08-21 23:22:59 +08:00
parent d92220b4bc
commit c1c17b5f4e
2 changed files with 40 additions and 5 deletions

View File

@@ -97,6 +97,8 @@ public class PostTag : ModelBase
[MaxLength(128)] public string Slug { get; set; } = null!; [MaxLength(128)] public string Slug { get; set; } = null!;
[MaxLength(256)] public string? Name { get; set; } [MaxLength(256)] public string? Name { get; set; }
[JsonIgnore] public ICollection<Post> Posts { get; set; } = new List<Post>(); [JsonIgnore] public ICollection<Post> Posts { get; set; } = new List<Post>();
[NotMapped] public int? Usage { get; set; }
} }
public class PostCategory : ModelBase public class PostCategory : ModelBase
@@ -105,6 +107,8 @@ public class PostCategory : ModelBase
[MaxLength(128)] public string Slug { get; set; } = null!; [MaxLength(128)] public string Slug { get; set; } = null!;
[MaxLength(256)] public string? Name { get; set; } [MaxLength(256)] public string? Name { get; set; }
[JsonIgnore] public ICollection<Post> Posts { get; set; } = new List<Post>(); [JsonIgnore] public ICollection<Post> Posts { get; set; } = new List<Post>();
[NotMapped] public int? Usage { get; set; }
} }
public class PostCollection : ModelBase public class PostCollection : ModelBase

View File

@@ -18,7 +18,7 @@ public class PostCategoryController(AppDatabase db) : ControllerBase
var categoriesQuery = db.PostCategories var categoriesQuery = db.PostCategories
.OrderBy(e => e.Name) .OrderBy(e => e.Name)
.AsQueryable(); .AsQueryable();
if (!string.IsNullOrEmpty(query)) if (!string.IsNullOrEmpty(query))
categoriesQuery = categoriesQuery categoriesQuery = categoriesQuery
.Where(e => EF.Functions.ILike(e.Slug, $"%{query}%")); .Where(e => EF.Functions.ILike(e.Slug, $"%{query}%"));
@@ -30,13 +30,30 @@ public class PostCategoryController(AppDatabase db) : ControllerBase
_ => categoriesQuery.OrderByDescending(e => e.CreatedAt) _ => categoriesQuery.OrderByDescending(e => e.CreatedAt)
}; };
} }
var totalCount = await categoriesQuery.CountAsync(); var totalCount = await categoriesQuery.CountAsync();
Response.Headers.Append("X-Total", totalCount.ToString()); Response.Headers.Append("X-Total", totalCount.ToString());
// Get categories with their post counts in a single query
var categories = await categoriesQuery var categories = await categoriesQuery
.Skip(offset) .Skip(offset)
.Take(take) .Take(take)
.Select(c => new
{
Category = c,
PostCount = c.Posts.Count
})
.ToListAsync(); .ToListAsync();
// Project results back to the original type and set the Usage property
var result = categories.Select(x =>
{
x.Category.Usage = x.PostCount;
return x.Category;
}).ToList();
return Ok(result);
return Ok(categories); return Ok(categories);
} }
@@ -51,7 +68,7 @@ public class PostCategoryController(AppDatabase db) : ControllerBase
var tagsQuery = db.PostTags var tagsQuery = db.PostTags
.OrderBy(e => e.Name) .OrderBy(e => e.Name)
.AsQueryable(); .AsQueryable();
if (!string.IsNullOrEmpty(query)) if (!string.IsNullOrEmpty(query))
tagsQuery = tagsQuery tagsQuery = tagsQuery
.Where(e => EF.Functions.ILike(e.Slug, $"%{query}%")); .Where(e => EF.Functions.ILike(e.Slug, $"%{query}%"));
@@ -63,15 +80,29 @@ public class PostCategoryController(AppDatabase db) : ControllerBase
_ => tagsQuery.OrderByDescending(e => e.CreatedAt) _ => tagsQuery.OrderByDescending(e => e.CreatedAt)
}; };
} }
var totalCount = await tagsQuery.CountAsync(); var totalCount = await tagsQuery.CountAsync();
Response.Headers.Append("X-Total", totalCount.ToString()); Response.Headers.Append("X-Total", totalCount.ToString());
// Get tags with their post counts in a single query
var tags = await tagsQuery var tags = await tagsQuery
.Skip(offset) .Skip(offset)
.Take(take) .Take(take)
.Select(t => new
{
Tag = t,
PostCount = t.Posts.Count
})
.ToListAsync(); .ToListAsync();
return Ok(tags); // Project results back to the original type and set the Usage property
var result = tags.Select(x =>
{
x.Tag.Usage = x.PostCount;
return x.Tag;
}).ToList();
return Ok(result);
} }
[HttpGet("categories/{slug}")] [HttpGet("categories/{slug}")]