繁体   English   中英

比较类列表中的属性

[英]compare properties in classes of list in class

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

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

首先,将从同一数据集中填充KbA和KbB,然后删除,添加和修改一些KbA子类。

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

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

为简单起见,我跳过了字节数组和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; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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