如何使用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
