Quickly compare two collections with LINQ, LAMBDA expressions, and delegates to find objects that need to be added, modified, deleted

Source: Internet
Author: User

This article requires some understanding of LINQ, LAMBDA expressions, and Delegates in C #.

At work, you often encounter scenarios that require a comparison of two sets, such as:

    1. Page collection data modifications that need to be saved to the database
    2. Full synchronization of upstream data to the system database

In these scenarios, you need to identify the data that needs to be added, updated, deleted, and because each application is inconsistent with the type of object that needs to be compared, a relatively generic method is written. In this process, the following 2 core concepts need to be understood:

    1. unique Identity comparison : If the unique identity of two objects is equal, the two objects are considered to represent the same thing in business (secondary attributes are not considered equal).
    2. Entity comparison : Indicates that two objects are not equal in the business (uniquely identifying equality, secondary attribute equality).

The code examples are as follows:

void Main () {//contrast source set var Source = generatestudent (1, 10000, 1000);    Target set var target = generatestudent (5000, 10000, 1000);    Unique identification comparison func<student, Student, bool> keycompartor = (s, t) = = S.id = t.id; Entity Equality comparison func<student, Student, bool> entitycompartor = (s, t) = S.id = T.id && s.name.equals (T.nam    e) && s.age = = T.age; Added before preparing func<student, student> insertaction = (s) + = {return new Student {Id =    S.id, Name = s.name, age = s.age, operation = "Insert"};    };        Pre-update Ready func<student, Student, student> updateaction = (s, t) = = {T.name = s.name;        T.age = S.age;        T.operation = "Update";    return t;    };        Prepare func<student before deletion, student> deleteaction = (t) + = {t.operation = "delete";    return t;    }; Remove equal objects removeduplicate (source, Target, Entitycompartor, (S1, S2) = S1. Id = = S2.    Id, Keycompartor);    Required new collection var insertingstudents = getinsertingentities (source, Target, Keycompartor, insertaction);    Collections that need to be updated var updatingstudents = getupdatingentities (source, Target, Keycompartor, Entitycompartor, updateaction);    The collection that needs to be deleted var deletingstudents = getdeletingentities (source, Target, Keycompartor, deleteaction);    Follow-up service//insertstudents (insertingstudents);    Updatestudents (updatingstudents); Deletestudents (deletingstudents);} Set de-heavy private void Removeduplicate<s, t> (list<s> source, list<t> Target, Func<s, T, bool> entity Compartor, Func<s, S, bool> sourcekeycompartor, Func<s, T, bool> keycomportor) {var sameentities = Sourc E.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))); Gets the collection of objects that need to be added PRIvate list<t> getinsertingentities<s, t> (list<s> source, list<t> Target, Func<s, T, bool>    Keycomportor, Func<s, t> insertaction) {var result = new list<t> (); foreach (var s in source) {var t = target.        FirstOrDefault (x = Keycomportor (s, x)); if (t = = null) {//does not exist in the target collection, new result is added.        ADD (Insertaction (s)); }} return result; Gets the collection of objects that need to be updated private list<t> getupdatingentities<s, t> (list<s> source, list<t> Target, Func <s, T, bool> Keycomportor, Func<s, T, bool> Entitycompartor, Func<s, T, t> updateaction) {var resu    lt = new list<t> (); foreach (var s in source) {var t = target.        FirstOrDefault (x = Keycomportor (s, x)); if (t! = null &&!entitycompartor (S, t)) {//is present in the target collection, but the secondary property is not equal, the result is updated.        ADD (Updateaction (S, t)); }} return result; Get collection of objects to delete private LiSt<t> Getdeletingentities<s, t> (list<s> source, list<t> Target, Func<s, T, bool> KeyCompo    Rtor, Func<t, t> deleteaction) {var result = new list<t> (); foreach (Var t in Target) {var s = source.        FirstOrDefault (x = Keycomportor (x, t)); if (s = = null) {//exists in the source collection, the result needs to be removed from the target collection.        ADD (Deleteaction (t)); }} return result;    Randomly generated test set private list<student> generatestudent (int minid, int maxid, int maxnumber) {var r = new Random ();    var students = new list<student> (); for (int i = 0; i < MaxNumber; i++) {students. ADD (new Student {Id = R.next (MiniD, maxid), name = $ "Name: {r.next (1, Ten)}", 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;}}

In the example, the source set uses the same object as the target collection, Student but in practice, the two types can be different, as long as the type of the target collection is eventually returned.

Above is my experience of the collection comparison, only to meet the small data volume of the business scenario, and not in the case of large data volume has been tuned. Here is also a point, if you have a better way, but also hope to enlighten.

Quickly compare two collections with LINQ, LAMBDA expressions, and delegates to find objects that need to be added, modified, deleted

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.