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

C#中GroupJoin查询返回结果的疑惑及原理咨询

关于C# LINQ左外连接的执行逻辑解释

先看你给出的代码定义:

public class Item
{
     public int Id { get; set;}
     public decimal Amount { get; set;}
}

var itemListOne = new List<Item>(){
    new Item{ Id = 1, Amount = 100 },
    new Item{ Id = 2, Amount = 200 },
    new Item{ Id = 3, Amount = 300 },
};

var itemListTwo = new List<Item>(){
    new Item{ Id = 1, Amount = 400 },
    new Item{ Id = 2, Amount = 500 }
};

以及你执行的LINQ查询:

var result = (from listOneItem in itemListOne
              join listTwoItem in itemListTwo on listOneItem.Id equals listTwoItem.Id into joinedItems
              from joinedItem in joinedItems.DefaultIfEmpty()
              select joinedItem != null ? joinedItem.Amount : 0).ToArray();

咱们一步步拆解这段代码的执行逻辑:

  • 第一步:GroupJoin分组
    join ... into joinedItems这行是LINQ的GroupJoin操作,它会遍历itemListOne的每个元素(也就是listOneItem),然后在itemListTwo里找出所有Id和当前listOneItem.Id相等的元素,把这些元素打包成一个集合,赋值给joinedItems。
    对应到你的数据:

    • 当listOneItem.Id=1时,joinedItems里只有itemListTwo中Id=1的元素(Amount=400)
    • 当listOneItem.Id=2时,joinedItems里只有itemListTwo中Id=2的元素(Amount=500)
    • 当listOneItem.Id=3时,itemListTwo里没有匹配的元素,所以joinedItems是空集合
  • 第二步:展开分组并处理空值
    from joinedItem in joinedItems.DefaultIfEmpty()这行是把分组后的集合“展开”成单个元素。DefaultIfEmpty()的作用是:如果joinedItems是空集合,就返回一个包含默认值(引用类型默认是null)的集合。
    所以这一步之后,每个listOneItem都会对应一个joinedItem:

    • Id=1的listOneItem对应joinedItem是itemListTwo的Id=1元素
    • Id=2的listOneItem对应joinedItem是itemListTwo的Id=2元素
    • Id=3的listOneItem对应joinedItem是null
  • 第三步:选择结果
    最后select joinedItem != null ? joinedItem.Amount : 0明确指定了要取的是joinedItem的Amount——也就是itemListTwo中匹配到的元素的金额,没有匹配到(joinedItem为null)就返回0。这就是为什么你得到的结果是[400,500,0],而不是itemListOne的金额。

如果你的需求是返回itemListOne的金额,只需要把select的部分改成select listOneItem.Amount即可,这样结果就是[100,200,300]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:57:41