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

C# 高性能关联右表字段到左列表 无需逐个指定对象字段的实现方案

性能优化方案

本质问题分析

你原有实现的性能瓶颈不是循环本身,而是循环内每次对accountNotesList执行全量遍历查找,时间复杂度为O(N*M),数据量级上来后耗时会指数级上升。

最优解法:字典预映射 + 循环赋值

这个方案时间复杂度仅为O(N+M),性能优于JOIN操作,且完全保留原有accountAging对象的所有字段,不需要手动赋值其他属性:

// 第一步:将备注列表预转为AccountId为键、Content为值的字典,仅遍历一次备注列表
// 如果存在同一AccountId对应多条备注的情况,改用ToLookup避免重复键报错
var noteDict = accountNotesList.ToDictionary(n => n.AccountId, n => n.Content);

// 第二步:遍历账龄列表,直接从字典查值,单次查找时间复杂度O(1)
foreach (var account in accountAging)
{
    if (noteDict.TryGetValue(account.AccountId, out var noteContent))
    {
        account.AccountsReceivableNotes = noteContent;
    }
}

如果存在同账号多条备注的场景,将字典替换为Lookup即可:

var noteLookup = accountNotesList.ToLookup(n => n.AccountId, n => n.Content);
foreach (var account in accountAging)
{
    account.AccountsReceivableNotes = noteLookup[account.AccountId].FirstOrDefault();
}

如果你坚持使用JOIN实现

不需要new新的AccountAging对象,直接在JOIN的结果投影中修改原有对象并返回即可,避免丢失其他字段的值:

var updatedAccountAging = accountAging
    .GroupJoin(
        accountNotesRepository.All.AsEnumerable(),
        a => a.AccountId,
        n => n.AccountId,
        (account, notes) => 
        {
            account.AccountsReceivableNotes = notes.Select(n => n.Content).FirstOrDefault();
            return account;
        }
    )
    .ToList();

注意事项

如果accountNotesRepository是EF等ORM的仓储实现,不要直接调用AsEnumerable()拉取全表数据,可先只查询需要的AccountId和Content两个字段,减少内存占用:

var accountNotesList = accountNotesRepository.All
    .Select(n => new { n.AccountId, n.Content })
    .ToList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:54:03