C#中比较两个Employee对象列表,获取属性不匹配的记录
解决两个Employee列表属性差异对比问题
要找出两个列表中EmployeeID一致但其他属性(Name、Gender、code)有变化的记录,可以通过以下两种实用方式实现:
1. LINQ Join 直接匹配筛选
通过LINQ的Join方法将两个列表按EmployeeID关联,然后筛选出属性不匹配的记录,代码简洁直观:
首先确保Employee类定义完整:
public class Employee { public int EmployeeID { get; set; } public string Name { get; set; } public string Gender { get; set; } public string code { get; set; } }
然后执行对比逻辑:
var oldlist = new List<Employee>{ new Employee(){EmployeeID=123,Name="XXXX",Gender="Male",code="CSE"}, new Employee(){EmployeeID=231,Name="FFF",Gender="Male",code="EC"}, new Employee(){EmployeeID=431,Name="GGG",Gender="Female",code="IT"}, new Employee(){EmployeeID=543,Name="DDD",Gender="Female",code="IT"} }; var newlist = new List<Employee>{ new Employee(){EmployeeID=123,Name="HHH",Gender="Male",code="IT"}, new Employee(){EmployeeID=231,Name="JJJ",Gender="FeMale",code="CSE"}, new Employee(){EmployeeID=431,Name="GGG",Gender="Female",code="IT"}, new Employee(){EmployeeID=543,Name="DDD",Gender="Female",code="IT"} }; // 筛选属性变化的记录,注意Gender忽略大小写比较 var changedRecords = from oldEmp in oldlist join newEmp in newlist on oldEmp.EmployeeID equals newEmp.EmployeeID where oldEmp.Name != newEmp.Name || !string.Equals(oldEmp.Gender, newEmp.Gender, StringComparison.OrdinalIgnoreCase) || oldEmp.code != newEmp.code select new { EmployeeID = oldEmp.EmployeeID, OldName = oldEmp.Name, NewName = newEmp.Name, OldGender = oldEmp.Gender, NewGender = newEmp.Gender, OldCode = oldEmp.code, NewCode = newEmp.code }; // 输出结果 foreach (var record in changedRecords) { Console.WriteLine($"EmployeeID: {record.EmployeeID}"); if (record.OldName != record.NewName) Console.WriteLine($" Name: {record.OldName} → {record.NewName}"); if (!string.Equals(record.OldGender, record.NewGender, StringComparison.OrdinalIgnoreCase)) Console.WriteLine($" Gender: {record.OldGender} → {record.NewGender}"); if (record.OldCode != record.NewCode) Console.WriteLine($" Code: {record.OldCode} → {record.NewCode}"); Console.WriteLine(); }
2. 字典优化查找(适合大数据量)
如果列表数据量较大,先将新列表转为Dictionary<int, Employee>可以大幅提升查找效率,避免多次遍历:
// 转换新列表为字典,以EmployeeID为键 var newEmpDictionary = newlist.ToDictionary(emp => emp.EmployeeID); var changedEmployees = new List<(Employee Old, Employee New)>(); foreach (var oldEmp in oldlist) { if (newEmpDictionary.TryGetValue(oldEmp.EmployeeID, out var newEmp)) { // 检查属性是否变化 bool hasChange = oldEmp.Name != newEmp.Name || !string.Equals(oldEmp.Gender, newEmp.Gender, StringComparison.OrdinalIgnoreCase) || oldEmp.code != newEmp.code; if (hasChange) { changedEmployees.Add((oldEmp, newEmp)); } } } // 遍历输出变化详情 foreach (var (oldEmp, newEmp) in changedEmployees) { Console.WriteLine($"EmployeeID {oldEmp.EmployeeID} 属性变更:"); if (oldEmp.Name != newEmp.Name) Console.WriteLine($" 姓名:{oldEmp.Name} → {newEmp.Name}"); if (!string.Equals(oldEmp.Gender, newEmp.Gender, StringComparison.OrdinalIgnoreCase)) Console.WriteLine($" 性别:{oldEmp.Gender} → {newEmp.Gender}"); if (oldEmp.code != newEmp.code) Console.WriteLine($" 部门编码:{oldEmp.code} → {newEmp.code}"); Console.WriteLine(); }
注意事项
- 大小写问题:例子中Gender存在
Male和FeMale的大小写差异,所以用StringComparison.OrdinalIgnoreCase忽略大小写比较,避免误判。 - 扩展属性:后续如果需要增加对比的属性,直接修改
where条件或hasChange的判断逻辑即可。 - ID不匹配场景:如果需要处理旧列表有但新列表没有(或反之)的记录,可以在遍历或LINQ中额外添加筛选逻辑。
内容的提问来源于stack exchange,提问作者Ramu
相关产品推荐
相关产品推荐

