使用Entity Framework Core的Include与Contains时无法返回预期结果
问题分析与解决
你的代码存在几个关键问题,直接导致了预期外的结果:
- 前置筛选逻辑错误:第一个
Where(c => c.Name.Contains(searchString))会先过滤掉所有名称不包含搜索字符串的课程,哪怕这些课程的Subcategory描述完全符合条件,这和你的需求完全冲突。 - 内存筛选的低效与风险:先调用
ToListAsync()把数据拉到内存再做二次筛选,不仅浪费数据库查询资源,还可能因为前置筛选已经把符合条件的记录过滤干净,导致后续内存筛选无数据返回。 - 空引用隐患:内存筛选时未判断
Subcategory是否为null,一旦存在未关联Subcategory的课程,会直接抛出空引用异常。
修正后的代码
把所有筛选逻辑合并到EF Core的LINQ查询中,让数据库层面完成筛选和关联加载,既高效又能保证数据正确:
public async Task<IEnumerable<Course>> GetAll(string searchString) { var query = _db.Courses .Include(c => c.Subcategory); // 用Lambda表达式更安全,避免字符串拼写错误 if (!string.IsNullOrEmpty(searchString)) { var lowerSearch = searchString.ToLower(); query = query.Where(c => c.Subcategory != null && c.Subcategory.FullDescription.ToLower().Contains(lowerSearch)); } return await query.ToListAsync(); }
额外说明
- 如果你的需求是同时匹配课程名称或Subcategory描述,可以把Where条件调整为:
query = query.Where(c => c.Name.ToLower().Contains(lowerSearch) || (c.Subcategory != null && c.Subcategory.FullDescription.ToLower().Contains(lowerSearch))); - 始终优先让数据库处理筛选逻辑,减少内存数据量,提升整体性能。
- 用Lambda形式的
Include比字符串参数更可靠,编译器会帮你检查属性名称的正确性。
内容的提问来源于stack exchange,提问作者Torekhan
相关产品推荐
相关产品推荐

