如何使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码)

本篇文章给大家带来的内容是关于如何使用linq、lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

在工作中,经常遇到需要对比两个集合的场景,如:

页面集合数据修改,需要保存到数据库

全量同步上游数据到本系统数据库

在这些场景中,需要识别出需要新增、更新、删除的数据,由于每次应用是,需要比较的对象类型不一致,因此写了个相对通用的方法。这个过程中,需要理解的有以下2个核心概念:

唯一标识比较: 如果两个对象的唯一标识相等,则认为这两个对象在业务上代表同一个东西(次要属性是否相等暂不考虑)。

实体比较:表示两个对象在业务是不是相等(唯一标识相等、次要属性相等)。

代码示例如下:

void Main(){    // 对比源集合    var source = GenerateStudent(1, 10000, 1000);    // 目标集合    var target = GenerateStudent(5000, 10000, 1000);    // 唯一标识比较    Func keyCompartor = (s, t) => s.Id == t.Id;    // 实体相等比较    Func entityCompartor = (s, t) => s.Id == t.Id && s.Name.Equals(t.Name) && s.Age == t.Age;    // 新增前准备    Func insertAction = (s) =>    {        return new Student        {            Id = s.Id,            Name = s.Name,            Age = s.Age,            Operation = "Insert"        };    };    // 更新前准备    Func updateAction = (s, t) =>    {        t.Name = s.Name;        t.Age = s.Age;        t.Operation = "Update";        return t;    };    // 删除前准备    Func 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 RemoveDuplicate(List source, List target, Func entityCompartor,    Func sourceKeyCompartor, Func 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 List GetInsertingEntities(List source, List target, Func keyComportor,    Func insertAction){    var result = new List();    foreach (var s in source)    {        var t = target.FirstOrDefault(x => keyComportor(s, x));        if (t == null)        {            // 目标集合中不存在,则新增            result.Add(insertAction(s));        }    }    return result;}// 获取需要更新的对象集合private List GetUpdatingEntities(List source, List target, Func keyComportor,    Func entityCompartor, Func updateAction){    var result = new List();    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 List GetDeletingEntities(List source, List target,    Func keyComportor, Func deleteAction){    var result = new List();    foreach (var t in target)    {        var s = source.FirstOrDefault(x => keyComportor(x, t));        if (s == null)        {            // 源集合中存在,目标集合中需要删除            result.Add(deleteAction(t));        }    }    return result;}// 随机生成测试集合private List GenerateStudent(int minId, int maxId, int maxNumber){    var r = new Random();    var students = new List();    for (int i = 0; i  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 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象(附代码)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1432878.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月17日 08:42:02
下一篇 2025年12月17日 08:42:07

相关推荐

  • C#中关于匿名委托和Lambda表达式的使用详解

    这篇文章主要为大家详细介绍了c#匿名委托与lambda表达式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 通过使用匿名委托(匿名方法),使编程变得更加灵活,有关委托与匿名委托请参考我的前一篇Blog《委托与匿名委托》。 继续之前示例,代码如下: static void Main(st…

    好文分享 2025年12月17日
    000
  • LINQ to SQL语句 Union/Intersect/Except

    linq to sql语句  union/intersect/except using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace BegVCSharp_23_15_Set…

    2025年12月17日
    000
  • C# 用Linq实现DataTable实现重复数据过滤

    未过滤前: 过滤后(仅会过滤掉完全一样的数据): 代码如下: DataTable dt = this.JsonToDataTable(“[{“Code”:”SortId”,”Name”:”SortId”},{“Code”:”SortCode”,”Name”:”编号”},{“Code”:”Soluti…

    2025年12月17日
    000
  • C#开始使用 LINQ (上)

    LINQ 简介 语言集成查询 (linq) 是 visual studio 2008 和 .net framework 3.5 版中引入的一项创新功能。 传统上,针对数据的查询都是以简单的字符串表示,而没有编译时类型检查或 IntelliSense 支持。此外,您还必须针对以下各种数据源学习一种不同…

    2025年12月17日
    000
  • python集合和列表推导式哪种方法去重快

    集合去重更快因其哈希实现,时间复杂度O(1);列表推导式查重为O(n²)较慢;需保序时推荐dict.fromkeys(),兼具性能与顺序。 在 Python 中,用集合(set)和列表推导式去重,集合去重更快。原因在于数据结构和时间复杂度的差异。 集合去重:高效且简洁 集合是哈希实现的,插入和查找平…

    2025年12月15日
    000
  • python判断两个集合是否相等

    两个集合相等当且仅当它们包含相同元素,使用==运算符判断。示例中set_a == set_b返回True,因元素相同;set_a == set_c返回False,因元素不同;空集比较返回True。注意:集合自动去重,==比较值而非身份,避免使用is。 在 Python 中,判断两个集合是否相等非常简…

    2025年12月14日
    000
  • Python中集合怎么使用 Python中集合使用教程

    集合是Python中用于存储唯一元素且无序的数据结构,支持高效去重和成员检测。它可通过花括号或set()函数创建,能执行交集、并集、差集等数学运算。集合元素必须为不可变类型(如数字、字符串、元组),不可变集合frozenset可作为字典键或嵌套在其他集合中。使用时需注意:{}创建的是字典而非集合,空…

    2025年12月14日
    000
  • Python中如何使用集合?去重与运算方法

    集合在python中用于去重和集合运算。1. 集合最常用于去重,如将列表转换为集合再转回列表即可去除重复元素,但结果顺序可能改变;2. 集合支持创建与判断操作,可通过set()或花括号创建,并高效判断元素是否存在;3. 集合支持交集(&)、并集(|)、差集(-)、对称差集(^)等运算,适用于…

    2025年12月14日 好文分享
    000
  • Python中的集合和frozenset是如何实现的?

    Python中的集合(set)和不可变集合(frozenset)是两种用于存储唯一元素的数据结构。它们分别属于可变和不可变对象,因此它们具有不同的性质和用法。本文将详细介绍集合和frozenset在Python中的实现方式,并提供具体代码示例。 一、集合(set)的实现方式:在Python中,集合使…

    2025年12月13日
    000
  • sqlserver根据id集合,批量插入。(巧用sqlserver内置函数)

    场景如下,传入的id,如1,3,4,88。可以在.net后台处理,但是我更习惯在数据库中操作。 插入数据时可以这样处理,直接贴代码。 CREATE PROCEDURE pro_CategorySave( @ids VARCHAR ( 400 ) , @type INT , @TemplateID I…

    2025年12月2日
    000
  • 在Java中如何使用多态处理集合中的不同对象_多态集合操作经验

    多态允许父类引用指向子类对象,通过将不同子类实例存入同一父类类型的集合中,实现统一管理和调用。例如定义Shape抽象类及其子类Circle、Rectangle,使用List存储对象,遍历集合时调用draw()方法会自动执行对应子类的实现,输出“绘制圆形”“绘制矩形”。新增Triangle类只需继承S…

    2025年12月2日 java
    000
  • Laravel如何使用集合(Collections)_强大的数组处理工具

    Laravel集合是数组的增强版,提供链式调用和丰富方法如map、filter、sortBy等,可优雅处理数据;适用于代码可读性优先的场景,但在性能敏感或需直接修改原数组时应使用原生PHP数组。 Laravel 的集合 (Collections) 就像打了鸡血的数组,提供了各种骚操作,让数据处理变得…

    2025年12月2日
    000
  • 在Java中如何使用Comparator结合Lambda表达式实现排序_Comparator Lambda指南

    Java 8中Comparator结合Lambda可简洁实现对象排序,如按年龄升序people.sort((p1, p2) -> p1.getAge() – p2.getAge());通过Comparator.comparing(Person::getAge)等方法可链式调用实现单…

    2025年12月2日 java
    000
  • java高频率基础面试题——集合框架部分

    1、ArrayList和Vector的区别 (更多面试题推荐:java面试题及答案) 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据…

    2025年12月2日 java
    000
  • Java函数与Lambda表達式的关系

    java 中,函数映射输入到输出,而 lambda 表达式是匿名的单行函数。两者密切相关,但 lambda 表达式更简洁、无需函数名,语法为:(参数1, 参数2, …, 参数n) -> 表达式。可将函数转换为 lambda 表达式,例如将函数 addone(x) 转换为 lambd…

    2025年12月1日 java
    000
  • Java 函数和 Java 方法在 Lambda 表达式中的应用

    java lambda 表达式可使用函数和方法作为参数,简化代码。函数和方法均接受输入并产生输出,可传递给 lambda 表达式,实现简洁和可读的代码。 Java 函数和方法在 Lambda 表达式中的应用 Lambda 表达式是一种简化 Java 代码的方式,允许将函数作为参数传递。在 Lambd…

    2025年11月29日 java
    000
  • 在Java中如何使用Collections.replaceAll替换集合元素_集合元素替换操作解析

    Collections.replaceAll方法用于替换List中所有与旧值相等的元素为新值,基于equals比较,返回是否发生替换。 在Java中,Collections.replaceAll 是一个静态方法,用于替换集合中所有与指定旧值相等的元素为新值。这个方法属于 java.util.Coll…

    2025年11月28日 java
    000
  • java 中怎么确保一个集合不能被修改?

    答案是使用Collections.unmodifiableXxx、Java 9的List.of()或Guava的Immutable集合来创建不可变集合,其中List.of()更简洁安全,Collections需注意原始集合暴露问题,Guava提供更丰富功能。 在 Java 中,如果你希望确保一个集合…

    2025年11月27日 java
    100
  • 在Java中使用lambda表达式的常见问题是什么?

    使用 lambda 表达式时遇到的常见问题包括:捕获值:lambda 表达式可以捕获其周围作用域中的值,但如果这些值随着时间改变,可能会导致意外的结果。类型推断:编译器有时无法推断 lambda 表达式的类型,需要使用显式类型声明来解决。并发问题:在多线程环境中,对共享变量的访问未同步会导致并发问题…

    2025年11月27日 java
    100
  • 如何使用lambda表达式创建Java函数?

    java 中的 lambda 表达式提供了一种简便的方法来创建匿名函数:使用箭头符号 (->) 定义函数签名并指定参数。用花括号 ({}) 包裹函数体。例如,一个接收两个整数并返回其和的 lambda 表达式为:(int a, int b) -> a + b; 使用 lambda 表达式…

    2025年11月27日 java
    000

发表回复

登录后才能评论
关注微信