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

如何基于EmployeeNumber合并两个对象列表并更新数据?

员工列表更新需求与解决方案

场景说明

我有两个员工列表:

  • 数据库来源列表(关联EmployeeId,为GUID类型):
EmployeeIdFirstNameLastNameEmployeeNumber
1234TomCruise98372829
5555JamesBond93932228
  • JSON来源列表(James Bond的姓氏已修改为Carter,EmployeeId为无效值):
EmployeeIdFirstNameLastNameEmployeeNumber
000-0000...TomCruise98372829
000-0000...JamesCarter93932228

需求:基于EmployeeNumber匹配,用数据库列表中的Id、FirstName、LastName更新JSON映射后的列表数据。

当前尝试的代码

// 从JSON获取员工列表
var retrievedEmployees = JsonSerializer.Deserialize<List<EmployeeDto>>(methodToRetrieveEmployees()))!.ToList();

// 通过AutoMapper映射为数据库实体格式
var mappedEmployees = _mapper.Map<IEnumerable<Employee>>(retrievedEmployees);

// 从数据库获取现有员工
var existingEmployeeFromDatabase = await GetExistingEmployees();

// 筛选出两边都存在的员工(仅匹配,未更新)
var employeesWithLatestUpdates = mappedEmployees
    .Where(y => existingEmployeeFromDatabase.Any(z => z.Number == y.Number)).ToList();

尝试过Union/Join但未成功,需要可行的解决方案。

解决方案

方案1:遍历更新原对象(推荐,保留原引用)

将数据库列表转为字典提升匹配效率,然后逐个更新映射后的员工对象:

// 从JSON获取并映射为实体列表
var retrievedEmployees = JsonSerializer.Deserialize<List<EmployeeDto>>(methodToRetrieveEmployees()))!.ToList();
var mappedEmployees = _mapper.Map<List<Employee>>(retrievedEmployees);

// 将数据库员工转为字典,以EmployeeNumber为键,减少匹配耗时
var dbEmployeeMap = (await GetExistingEmployees())
    .ToDictionary(emp => emp.EmployeeNumber);

// 遍历映射列表,匹配数据库数据并更新字段
foreach (var mappedEmp in mappedEmployees)
{
    if (dbEmployeeMap.TryGetValue(mappedEmp.EmployeeNumber, out var dbEmp))
    {
        mappedEmp.EmployeeId = dbEmp.EmployeeId;
        mappedEmp.FirstName = dbEmp.FirstName;
        mappedEmp.LastName = dbEmp.LastName;
        // 若有其他需要同步的字段,可在此添加
    }
}

// mappedEmployees即为更新后的最终列表
var employeesWithLatestUpdates = mappedEmployees;

方案2:用LINQ Join生成新对象

如果不需要保留原映射对象的引用,可以直接通过Join生成更新后的新列表:

var retrievedEmployees = JsonSerializer.Deserialize<List<EmployeeDto>>(methodToRetrieveEmployees()))!.ToList();
var mappedEmployees = _mapper.Map<IEnumerable<Employee>>(retrievedEmployees);
var existingEmployeeFromDatabase = await GetExistingEmployees();

var employeesWithLatestUpdates = mappedEmployees
    .Join(
        existingEmployeeFromDatabase,
        mappedEmp => mappedEmp.EmployeeNumber,
        dbEmp => dbEmp.EmployeeNumber,
        (mappedEmp, dbEmp) => new Employee
        {
            EmployeeId = dbEmp.EmployeeId,
            FirstName = dbEmp.FirstName,
            LastName = dbEmp.LastName,
            EmployeeNumber = mappedEmp.EmployeeNumber,
            // 其他字段根据需求选择从mappedEmp或dbEmp取值
        }
    )
    .ToList();

方案说明

  • 方案1适合需要保留原映射对象引用的场景,且字典匹配的效率远高于多次Any遍历,数据量越大优势越明显。
  • 方案2通过LINQ直接生成新对象,代码更简洁,但会丢弃原映射对象的引用。
  • 两种方案都严格基于EmployeeNumber匹配,确保用数据库的最新Id、FirstName、LastName覆盖JSON映射的数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:55:32