如何使用.Include()方法简化现有LINQ多表关键词查询语句
EF Core 用Include简化关联搜索实现
你当前的逻辑本质是查询满足任意以下条件的未禁用Plate:
- Plate的Name字段匹配搜索关键词
- 关联的Search表中存在SearchTerm匹配关键词的记录,且记录关联的Plate为当前记录
原实现分3次数据库查询后在内存做并集,存在冗余数据库往返,完全可以通过配置导航属性+Include()合并为单次查询。
前置准备:配置实体导航属性
要使用Include()必须先配置两个表的关联关系,对应实体类添加导航属性即可(EF Core会按约定自动识别外键,如果你用的是PlatformId作为外键,把下方的PlateId替换成你的实际字段名就行):
public class Plate { public int Id { get; set; } public string Name { get; set; } public PlateStatus Status { get; set; } // 关联当前Plate的所有Search记录集合导航 public ICollection<Search> Searches { get; set; } } public class Search { public int Id { get; set; } public string SearchTerm { get; set; } // 关联Plates表的外键 public int PlateId { get; set; } // 单条Search关联的Plate导航属性 public Plate Plate { get; set; } }
简化后实现代码
if (!string.IsNullOrWhiteSpace(request.Keyword)) { // 提前处理关键词,避免重复格式化 var normalizedKeyword = request.Keyword.Trim().ToLower(); plates = await _db.Plates // 如果你需要同时返回匹配的Search关联记录就保留这行Include,不需要可以删掉,不影响过滤逻辑 .Include(p => p.Searches) .OrderBy(p => p.Name) .Where(p => p.Status != PlateStatus.Disabled && ( p.Name.ToLower().Contains(normalizedKeyword) || p.Searches.Any(s => s.SearchTerm.ToLower().Contains(normalizedKeyword)) )) .ToListAsync(ct); }
注意点
Include()的核心作用是预加载关联数据,跨表过滤是通过导航属性直接在Where中写逻辑实现的,不需要像原代码一样手动查询关联Id再做匹配- 该实现只会产生1次数据库查询,过滤逻辑会被翻译成SQL的EXISTS条件和OR逻辑,在数据库侧完成并集去重,性能远高于多次查询+内存Union的写法
- 原代码中
_db.Plate和_db.Plates的DbSet引用不一致属于笔误,简化后统一为_db.Plates即可
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

