如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码)
导读:收集整理的这篇文章主要介绍了如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码),觉得挺不错的,现在分享给大家,也给大家做个参考。本篇文章给大家带来的内容是关于如何使用LINQ、Lambd...
收集整理的这篇文章主要介绍了如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码),觉得挺不错的,现在分享给大家,也给大家做个参考。本篇文章给大家带来的内容是关于如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。在工作中,经常遇到需要对比两个集合的场景,如:
页面集合数据修改,需要保存到数据库
全量同步上游数据到本系统数据库
在这些场景中,需要识别出需要新增、更新、删除的数据,由于每次应用是,需要比较的对象类型不一致,因此写了个相对通用的方法。这个过程中,需要理解的有以下2个核心概念:
唯一标识比较: 如果两个对象的唯一标识相等,则认为这两个对象在业务上代表同一个东西(次要属性是否相等暂不考虑)。
实体比较:表示两个对象在业务是不是相等(唯一标识相等、次要属性相等)。
代码示例如下:
void Main(){ // 对比源集合 VAR source = Generatestudent(1, 10000, 1000); // 目标集合 var target = GenerateStudent(5000, 10000, 1000); // 唯一标识比较 FuncStudent, Student, bool> keyCompartor = (s, t) => s.Id == t.Id; // 实体相等比较 FuncStudent, Student, bool> entITyCompartor = (s, t) => s.Id == t.Id & & s.Name.Equals(t.Name) & & s.Age == t.Age; // 新增前准备 FuncStudent, Student> insertAction = (s) => { return new Student { Id = s.Id, Name = s.Name, Age = s.Age, operation = "Insert" } ; } ; // 更新前准备 FuncStudent, Student, Student> updateAction = (s, t) => { t.Name = s.Name; t.Age = s.Age; t.OPEration = "Update"; return t; } ; // 删除前准备 FuncStudent, Student> deleteAction = (t) => { t.Operation = "Delete"; return t; } ; // 去掉相等对象 RemoveDuplicate(source, target, entityCompartor, (s1, s2) => s1.Id == s2.Id, keyCompartor); // 需要新增的集合 var insertingStudents = GetInsertingEntities(source, target, keyCompartor, insertAction); // 需要更新的集合 var updatingStudents = GetUpdatingEntities(source, target, keyCompartor, entityCompartor, updateAction); // 需要删除的集合 var deletingStudents = GetDeletingEntities(source, target, keyCompartor, deleteAction); // 后续业务 // InsertStudents(insertingStudents); // UpdateStudents(updatingStudents); // DeleteStudents(deletingStudents); } // 集合去重PRivate void RemoveDuplicateS, T> (ListS> source, ListT> target, FuncS, T, bool> entityCompartor, FuncS, S, bool> sourceKeyCompartor, FuncS, T, bool> keyComportor){ var sameEntities = source.Where(s => target.Exists(t => entityCompartor(s, t))).ToList(); source.RemoveAll(s => sameEntities.Exists(s2 => sourceKeyCompartor(s, s2))); target.RemoveAll(t => sameEntities.Exists(s => keyComportor(s, t))); } // 获取需要新增的对象集合private ListT> GetInsertingEntitiesS, T> (ListS> source, ListT> target, FuncS, T, bool> keyComportor, FuncS, T> insertAction){ var result = new ListT> (); foreach (var s in source) { var t = target.FirstOrDefault(x => keyComportor(s, x)); if (t == null) { // 目标集合中不存在,则新增 result.Add(insertAction(s)); } } return result; } // 获取需要更新的对象集合private ListT> GetUpdatingEntitiesS, T> (ListS> source, ListT> target, FuncS, T, bool> keyComportor, FuncS, T, bool> entityCompartor, FuncS, T, T> updateAction){ var result = new ListT> (); foreach (var s in source) { var t = target.FirstOrDefault(x => keyComportor(s, x)); if (t != null & & !entityCompartor(s, t)) { // 目标集合中存在,但是次要属性不相等,则更新 result.Add(updateAction(s, t)); } } return result; } // 获取需要删除的对象集合private ListT> GetDeletingEntitiesS, T> (ListS> source, ListT> target, FuncS, T, bool> keyComportor, FuncT, T> deleteAction){ var result = new ListT> (); foreach (var t in target) { var s = source.FirstOrDefault(x => keyComportor(x, t)); if (s == null) { // 源集合中存在,目标集合中需要删除 result.Add(deleteAction(t)); } } return result; } // 随机生成测试集合private ListStudent> GenerateStudent(int minId, int maxId, int maxNumber){ var r = new Random(); var students = new ListStudent> (); for (int i = 0; i maxNumber; i++) { students.Add(new Student { Id = r.Next(minId, maxId), Name = $"name: { r.Next(1, 10)} ", Age = r.Next(6, 10) } ); } return students.GroupBy(s => s.Id).Select(s => s.First()).ToList(); } public class Student{ public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Operation { get; set; } }
例子中源集合与目标集合使用了相同的对象Student
,但实际使用中,两者的类型可以不一样,只要最终返回目标集合的类型就可以了。
上面是我对集合比较的一点心得,只满足了小数据量的业务情景,并没有在大数据量的情况下做过调优。在这里也算是抛砖引玉,大家要是有更好的办法,还希望不吝赐教。
以上就是如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码)的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码)
本文地址: https://pptw.com/jishu/593196.html