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

EF Core中如何实现按条件关联不同实体的左连接查询

EF Core 条件左连接查询实现方案

前置准备

首先确保你的EF Core上下文与对应实体已正确定义,参考结构如下:

// 交易表实体
public class Transaction
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    /// <summary>
    /// 订单类型:0=销售单,1=采购单,可扩展
    /// </summary>
    public int OrderType { get; set; }
    public decimal Amount { get; set; }
}

// 销售单实体
public class Sale
{
    public int Id { get; set; }
    public string OrderNo { get; set; }
    // 其他销售单字段省略
}

// 采购单实体
public class Purchase
{
    public int Id { get; set; }
    public string OrderNo { get; set; }
    // 其他采购单字段省略
}

// 数据库上下文
public class AppDbContext : DbContext
{
    public DbSet<Transaction> Transactions { get; set; }
    public DbSet<Sale> Sales { get; set; }
    public DbSet<Purchase> Purchases { get; set; }
    // 上下文其他配置省略
}

具体查询写法

以下两种写法均可生成与你提供的原生SQL逻辑完全一致的语句,仅触发一次数据库查询,解决多次调用的性能问题。

方式1:查询语法(可读性更高)

var query = from ap in _dbContext.Transactions
            // 条件左连接销售表
            join s in _dbContext.Sales 
                on new { OrderId = ap.OrderId, Type = 0 } equals new { OrderId = s.Id, Type = 0 } into sGroup
            from s in sGroup.DefaultIfEmpty()
            // 条件左连接采购表
            join p in _dbContext.Purchases
                on new { OrderId = ap.OrderId, Type = 1 } equals new { OrderId = p.Id, Type = 1 } into pGroup
            from p in pGroup.DefaultIfEmpty()
            select new 
            {
                ap.Id,
                ap.OrderId,
                ap.OrderType,
                ap.Amount,
                // 空合并运算符会自动转换为SQL的COALESCE函数
                OrderNo = s.OrderNo ?? p.OrderNo
                // 如需其他字段可自行补充
            };
// 执行查询获取结果
var result = await query.ToListAsync();

方式2:方法语法

var result = await _dbContext.Transactions
    // 左连接销售表
    .GroupJoin(
        _dbContext.Sales,
        ap => new { ap.OrderId, Type = 0 },
        s => new { OrderId = s.Id, Type = 0 },
        (ap, sGroup) => new { ap, Sale = sGroup.FirstOrDefault() }
    )
    // 左连接采购表
    .GroupJoin(
        _dbContext.Purchases,
        temp => new { temp.ap.OrderId, Type = 1 },
        p => new { OrderId = p.Id, Type = 1 },
        (temp, pGroup) => new { temp.ap, temp.Sale, Purchase = pGroup.FirstOrDefault() }
    )
    // 映射结果
    .Select(res => new 
    {
        res.ap.Id,
        res.ap.OrderId,
        res.ap.OrderType,
        res.ap.Amount,
        OrderNo = res.Sale.OrderNo ?? res.Purchase.OrderNo
    })
    .ToListAsync();

扩展说明

如果后续OrderType新增了其他取值,只需要按照上述格式新增对应表的左连接逻辑,同时在空合并运算的参数中加入对应表的字段即可兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:36:03