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

如何用LINQ to SQL实现带过滤后子列表的父对象查询

嘿,我来帮你把那条SQL转换成LINQ to SQL查询,同时实现你要的「包含已过滤子列表的对象集合」的需求~

首先先明确原SQL的逻辑:关联Pages、Translations、Texts三张表,过滤出LanguageId=1的文本,同时保证Translation的NeutralText和Page的TitleNeutralTextId匹配。

方法一:基于查询语法(和原SQL结构最接近,易读性高)

假设你的DbContext里有Translations和Texts两个DbSet,且this.Queryable()返回的是IQueryable<Page>,可以这么写:

var query = from p in this.Queryable()
            join translation in dbContext.Translations 
                on p.TranslationId equals translation.Id
            join text in dbContext.Texts 
                on translation.Id equals text.TranslationId
            where text.LanguageId == 1 && translation.NeutralText == p.TitleNeutralTextId
            select new {
                Page = p,
                MatchingText = text
            };

不过如果你的需求是每个Page对象附带符合条件的子文本列表(而不是一对一的平级结果),那需要用分组来实现:

方法二:分组获取带过滤子列表的Page集合

如果想返回每个Page对应的所有符合条件的Texts子集合,可以用分组查询:

// 先定义一个类来封装结果(如果不需要强类型也可以用匿名类)
public class PageWithFilteredTexts
{
    public Page Page { get; set; }
    public IEnumerable<Text> FilteredTexts { get; set; }
}

// 构建查询
var query = this.Queryable()
                // 第一步关联Page和Translation
                .Join(dbContext.Translations,
                      page => page.TranslationId,
                      translation => translation.Id,
                      (page, translation) => new { page, translation })
                // 过滤Translation和Page的NeutralText匹配条件
                .Where(joinResult => joinResult.translation.NeutralText == joinResult.page.TitleNeutralTextId)
                // 第二步关联Text
                .Join(dbContext.Texts,
                      joinResult => joinResult.translation.Id,
                      text => text.TranslationId,
                      (joinResult, text) => new { joinResult.page, text })
                // 过滤LanguageId=1的文本
                .Where(finalResult => finalResult.text.LanguageId == 1)
                // 按Page分组,把同一个Page的所有符合条件的Texts归为一组
                .GroupBy(finalResult => finalResult.page)
                // 投影成我们需要的带子列表的对象
                .Select(group => new PageWithFilteredTexts
                {
                    Page = group.Key,
                    FilteredTexts = group.Select(item => item.text)
                });

方法三:利用导航属性简化(如果实体类配置了导航关系)

如果你的实体类已经配置了导航属性(比如Page有Translation属性,Translation有Texts集合属性),那代码会更简洁:

var query = this.Queryable()
                // 先过滤出符合条件的Page
                .Where(page => page.Translation.NeutralText == page.TitleNeutralTextId 
                            && page.Translation.Texts.Any(text => text.LanguageId == 1))
                // 投影时只取符合条件的Texts子列表
                .Select(page => new PageWithFilteredTexts
                {
                    Page = page,
                    FilteredTexts = page.Translation.Texts.Where(text => text.LanguageId == 1)
                });

这种写法更直观,LINQ to SQL会自动帮你生成对应的关联查询,和你给出的SQL逻辑一致。

内容的提问来源于stack exchange,提问作者David Létourneau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:50:25