比较类中列表类的属性

时间:2013-09-11 13:17:13

标签: c# linq visual-studio class compare

我所拥有的是两个类,每个类都包含具有不同类型属性的类列表。第一个列表是第二个列表的更新版本,我需要找到所有差异(列表和更新类中删除/添加的类)。

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();

首先从同一个DataSet填充KbA和KbB,然后我删除,添加和修改一些KbA子类。

现在我需要将KbA与KbB进行比较,以找出差异所在。我需要KbA中已删除或添加的类的ID以及修改后的Child-Classes属性的确切更改。我该怎么办?优先使用Linq。

2 个答案:

答案 0 :(得分: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
    }
}

您可以使用IntersectExcept LINQ方法

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

答案 1 :(得分: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; }
}