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

使用LINQ填充父子结构的最优方法及性能疑问

关于LINQ父子结构填充的性能问题解答

首先明确:你担心的情况是对的——原代码里的嵌套查询会针对每个父节点遍历一次整个子表。如果有1000个父节点,就会执行1000次子查询,每次都全量扫描Children表,数据量越大,性能损耗越明显。

另外注意原代码里的语法错误:where条件中的判断应该用==,不是=,否则会编译失败。

优化方案:预分组子表

核心思路是先对子表按ParentId做一次分组,把结果存到字典里,之后遍历父节点时直接通过键值对快速查找,这样只需要遍历子表一次,整体时间复杂度从O(n*m)降到O(n+m)。

优化后的代码示例:

var ds = myDAL.GetDataSet("mySP");
var Parent = ds.Tables[0];
var Children = ds.Tables[1];

// 先将子表按ParentId分组,存入字典
var childGroups = Children.AsEnumerable()
    .GroupBy(c => c.Field<int>("ParentId"))
    .ToDictionary(g => g.Key, g => g.Select(c => new 
    {
        Id = c.Field<int>("Id"),
        Name = c.Field<string>("Name")
    }).ToList());

// 遍历父节点,直接从字典取对应子项
var ParentChildren = from p in Parent.AsEnumerable()
                     let parentId = p.Field<int>("Id")
                     select new 
                     { 
                         Id = parentId, 
                         Name = p.Field<string>("Name"), 
                         Children = childGroups.TryGetValue(parentId, out var kids) ? kids : Enumerable.Empty<object>()
                     };

优化说明

  • 第一步的GroupBy+ToDictionary只会执行一次,把所有子节点按父ID归类好。
  • 遍历父节点时,通过TryGetValue可以O(1)时间拿到对应的子节点集合,避免了重复扫描子表。
  • 如果某个父节点没有子节点,用Enumerable.Empty<object>()返回空集合,保证结构一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:18:39