基于SQL/LINQ的多层级关联多表博客全字段检索方案咨询
实现多层级关联多表搜索的LINQ方案
第一步:扩展搜索参数类
首先在原有的TableSearchOptions类中新增可选搜索字段,用户传值的字段才会触发对应过滤逻辑:
public class TableSearchOptions { public int? Skip { get; set; } public int? Take { get; set; } // 以下为新增可选搜索字段 public string? SearchUserName { get; set; } public string? SearchPostContent { get; set; } public string? SearchCommentContent { get; set; } public DateTime? StartPostDate { get; set; } public DateTime? EndPostDate { get; set; } // 点赞/踩状态:null=不限制,true=匹配有点赞的记录,false=匹配有踩的记录 public bool? SearchLikeStatus { get; set; } }
第二步:实现动态搜索方法
通过链式拼接LINQ条件实现多字段可选过滤,关联层级用Any()方法匹配子集记录:
public async Task<object> Search(TableSearchOptions searchOptions) { try { // 初始化查询,预加载所有关联导航属性 var query = appDbContext.BlogPosts .AsNoTracking() // 只读查询添加该配置大幅提升性能 .Include(x => x.BlogUser) .Include(e => e.BlogComments) .ThenInclude(p => p.BlogUser) .Include(e => e.BlogComments) .ThenInclude(p => p.BlogCommentLikeAndDislikes); // 动态追加搜索条件,参数为空则不加入过滤逻辑 // 1. 按博客用户名模糊搜索 if (!string.IsNullOrWhiteSpace(searchOptions.SearchUserName)) { query = query.Where(p => p.BlogUser.UserName.Contains(searchOptions.SearchUserName)); } // 2. 按文章内容模糊搜索 if (!string.IsNullOrWhiteSpace(searchOptions.SearchPostContent)) { query = query.Where(p => p.Post.Contains(searchOptions.SearchPostContent)); } // 3. 按评论内容模糊搜索 if (!string.IsNullOrWhiteSpace(searchOptions.SearchCommentContent)) { query = query.Where(p => p.BlogComments.Any(c => c.Comment.Contains(searchOptions.SearchCommentContent))); } // 4. 按文章发布日期范围搜索 if (searchOptions.StartPostDate.HasValue) { query = query.Where(p => p.PostDate >= searchOptions.StartPostDate.Value); } if (searchOptions.EndPostDate.HasValue) { // 结束日期加1天,覆盖当天所有时段的记录 query = query.Where(p => p.PostDate < searchOptions.EndPostDate.Value.AddDays(1)); } // 5. 按点赞/踩状态搜索 if (searchOptions.SearchLikeStatus.HasValue) { query = query.Where(p => p.BlogComments .Any(c => c.BlogCommentLikeAndDislikes .Any(l => l.IsLike == searchOptions.SearchLikeStatus.Value))); } // 执行分页查询返回结果 var data = await query .Skip(searchOptions.Skip ?? 0) .Take(searchOptions.Take ?? 3) .ToListAsync(); return data; } catch (Exception e) { // 可在此处添加异常日志逻辑 return null; } }
补充说明
- 上述方案默认所有生效的搜索条件为
AND逻辑,如果需要改为匹配任意条件的OR逻辑,可以通过表达式树拼接实现更灵活的条件组合。 - 若偏好原生SQL实现,可以通过四表JOIN编写查询语句,配合EF Core的
FromSqlRaw()方法执行后再加载关联属性即可。
内容的提问来源于stack exchange,提问作者Pias Uddin Jibon
相关产品推荐
相关产品推荐

