You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 01:51:25