简体   繁体   中英

compare properties in classes of list in class

What I've got are two classes which each contain Lists of Classes with propperties of different types. The first list is an updated version of the second and i need to find all differences (deleted/added classes in lists and updated classes).

public class ClassOfKb
{
    public List<Data> KbData {get;set;}
    public List<Info> KbInfo {get;set;}
}

class Data
{
    public Guid ID {get;set}
    public byte[] file {get;set}
    public string name {get;set}
}
class Info
{
    public Guid ID {get;set}
    public string text {get;set}
    public DateTime date {get;set}
}


ClassOfKb KbA = new ClassOfKb();
ClassOfKb KbB = new ClassOfKb();

first KbA and KbB will be filled from the same DataSet, then i delete, add and modify some of KbA Child-Classes.

now i need to compare KbA with KbB to find out where the differences are. i need the ID of deleted or added classes in KbA and the exact changes of modified Child-Classes properties. How would i do this? Preffered with Linq.

I suggest that create two comparers one for Data and one for Info

class DataComparer : IEqualityComparer<Data>
{
    public bool Equals(Data x, Data y)
    {
        //logic to compare x to y and return true when they are equal
    }
    public int GetHashCode(Data d)
    {
        //logic to return a hash code
    }
}

class InfoComparer : IEqualityComparer<Info>
{
    public bool Equals(Info x, Info y)
    {
        //logic to compare x to y and return true when they are equal
    }
    public int GetHashCode(Info i)
    {
        //logic to return a hash code
    }
}

The you can use Intersect and Except LINQ methods

 IEnumerable<Data> DataInAandNotInB = KbA.KbData.Except(KbB.KbData,new DataComparer());
 IEnumerable<Info> InfoInAandInB = KbA.KbInfo.Intersect(KbB.KbInfo,new InfoComparer ());

For simplicity, I skipped comparison of the byte array and DateTime data membes, only left the IDs and the string data members, but to add them you will need some small modification. The test is very-very basic, but shows all three of the changes options:

static void Main(string[] args)
    {
        ClassOfKb KbA = new ClassOfKb();
        ClassOfKb KbB = new ClassOfKb();

        // Test data --------

        Data data1 = new Data() { ID = Guid.NewGuid(), name = "111" };
        Data data2 = new Data() { ID = Guid.NewGuid(), name = "222" };
        Data data2_changed = new Data() { ID = data2.ID, name = "222_changed" };
        Data data3 = new Data() { ID = Guid.NewGuid(), name = "333" };

        Info info1 = new Info() { ID = Guid.NewGuid(), text = "aaa" };
        Info info2 = new Info() { ID = Guid.NewGuid(), text = "bbb" };
        Info info2_changed = new Info() { ID = info2.ID, text = "bbb_changed" };
        Info info3 = new Info() { ID = Guid.NewGuid(), text = "ccc" };

        KbA.KbData.Add(data1);
        KbA.KbData.Add(data2);

        KbA.KbInfo.Add(info1);
        KbA.KbInfo.Add(info2);

        KbB.KbData.Add(data2_changed);
        KbB.KbData.Add(data3);

        KbB.KbInfo.Add(info2_changed);
        KbB.KbInfo.Add(info3);

        // end of test data ---------


        // here is the solution:
        var indexes = Enumerable.Range(0, KbA.KbData.Count);

        var deleted = from i in indexes
                      where !KbB.KbData.Select((n) => n.ID).Contains(KbA.KbData[i].ID)
                      select new
                      {
                          Name = KbA.KbData[i].name,
                          KbDataID = KbA.KbData[i].ID,
                          KbInfoID = KbA.KbInfo[i].ID
                      };

        Console.WriteLine("deleted:");
        foreach (var val in deleted)
        {
            Console.WriteLine(val.Name);
        }

        var added = from i in indexes
                    where !KbA.KbData.Select((n) => n.ID).Contains(KbB.KbData[i].ID)
                    select new
                    {
                        Name = KbB.KbData[i].name,
                        KbDataID = KbB.KbData[i].ID,
                        KbInfoID = KbB.KbInfo[i].ID
                    };

        Console.WriteLine("added:");
        foreach (var val in added)
        {
            Console.WriteLine(val.Name);
        }

        var changed = from i in indexes
                      from j in indexes
                      where KbB.KbData[i].ID == KbA.KbData[j].ID &&
                            (//KbB.KbData[i].file != KbA.KbData[j].file ||
                            KbB.KbData[i].name != KbA.KbData[j].name ||
                          //KbB.KbInfo[i].date != KbA.KbInfo[j].date ||
                            KbB.KbInfo[i].text != KbA.KbInfo[j].text
                            )
                      select new
                      {
                          Name = KbA.KbData[j].name,
                          KbDataID = KbA.KbData[j].ID,
                          KbInfoID = KbA.KbInfo[j].ID
                      };

        Console.WriteLine("changed:");
        foreach (var val in changed)
        {
            Console.WriteLine(val.Name);
        }

        Console.ReadLine();
    }
}

public class ClassOfKb
{
    public List<Data> KbData = new List<Data>();
    public List<Info> KbInfo = new List<Info>();
}

public class Data
{
    public Guid ID { get; set; }
    public byte[] file { get; set; }
    public string name { get; set; }
}

public class Info
{
    public Guid ID { get; set; }
    public string text { get; set; }
    public DateTime date { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM