0

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.

4

2 回答 2

1

我建议创建两个比较器,一个用于Data,一个用于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
    }
}

你可以使用IntersectExceptLINQ 方法

 IEnumerable<Data> DataInAandNotInB = KbA.KbData.Except(KbB.KbData,new DataComparer());
 IEnumerable<Info> InfoInAandInB = KbA.KbInfo.Intersect(KbB.KbInfo,new InfoComparer ());
于 2013-09-11T13:59:08.837 回答
0

为简单起见,我跳过了字节数组和 DateTime 数据成员的比较,只留下了 ID 和字符串数据成员,但要添加它们,您需要进行一些小的修改。该测试非常基础,但显示了所有三个更改选项:

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; }
}
于 2013-09-11T23:36:23.773 回答