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

如何使用Lambda语法在LINQ to SQL中实现Cross Apply关联查询

LINQ to SQL Lambda 实现方案

核心逻辑对应

先拆解原SQL的执行流程,确保翻译的逻辑完全对齐:

  • 第一步筛选Table_A中Status = 10的所有记录
  • 对每条A记录,关联Table_B与Table_C(关联条件为两表Id相等),仅保留关联结果中Id与当前A记录Id一致的数据,按c.Time升序取最早的1条时间值
  • 筛选掉关联得到的时间小于等于2021-03-09的无效记录
  • 最终返回A的全字段与关联出的最早时间值

Lambda 实现代码

假设你已经初始化了对应映射的DataContext实例,可直接使用如下代码:

// 定义过滤用的目标日期,避免硬编码带来的解析问题
var thresholdDate = new DateTime(2021, 3, 9);

var resultQuery = dbContext.Table_A
    // 对应外层 where a.Status = 10 过滤
    .Where(a => a.Status == 10)
    // 对应 CROSS APPLY 子查询逻辑
    .SelectMany(
        // 对每条A记录执行的子查询,等价于原SQL中apply块的内容
        a => dbContext.Table_B
            // 对应 inner join Table_C c on c.Id = b.Id
            .Join(
                tableC: dbContext.Table_C,
                outerKeySelector: b => b.Id,
                innerKeySelector: c => c.Id,
                resultSelector: (b, c) => new { b, c }
            )
            // 对应子查询内 where b.Id = a.Id 的匹配条件
            .Where(joinSet => joinSet.b.Id == a.Id)
            // 对应 order by c.Time asc
            .OrderBy(joinSet => joinSet.c.Time)
            // 对应 top 1
            .Take(1)
            .Select(joinSet => joinSet.c.Time),
        // 定义最终结果的投影结构
        (a, earliestTime) => new 
        {
            A信息 = a, // 直接包含Table_A所有字段,等价于原SQL select * from TABLE_A a
            关联最早时间 = earliestTime
        }
    )
    // 对应 where d.Time > '2021-03-09' 的过滤条件
    .Where(res => res.关联最早时间 > thresholdDate);

关键逻辑说明

  • 上述写法会被LINQ to SQL Provider直接翻译为SQL端的CROSS APPLY语法,不会把数据拉取到内存后做关联,性能与原生SQL一致
  • SelectMany的语义天然匹配CROSS APPLY的行为:如果子查询返回空集合,对应的外层A记录会被自动排除,和原SQL的执行结果完全一致
  • 针对当前表结构的特殊情况优化:由于Table_B和Table_C都以Id为主键,两表的Id关联本身是1:1的关系,原SQL中的top 1逻辑可以简化,生成的SQL会更简洁高效,优化后的子查询写法为:
    a => dbContext.Table_C.Where(c => c.Id == a.Id).Select(c => c.Time)
    

内容的提问来源于stack exchange,提问作者Olga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 12:36:03