C# 仅在两个分层列表之间保存更改

C# 仅在两个分层列表之间保存更改,c#,algorithm,list,tree,treeview,C#,Algorithm,List,Tree,Treeview,这是一个非常概念化的问题,我可能会得到-ves。但是请容忍我。 我有两个列表,其中包含来自两个TreeView的内存中的数据层次结构。一份原件和一份更新件myType具有自连接属性,因此是树结构。 目前,我正在清除整个表,并将更新后的列表保存到数据库中。 既然这样做效率不高,我该如何比较它们并仅将更改保存到我的数据库中? 以下是一个场景: List<Person> tree1 = new List<Person>(); tree1.Add (

这是一个非常概念化的问题,我可能会得到-ves。但是请容忍我。
我有两个
列表
,其中包含来自两个TreeView的内存中的数据层次结构。一份原件和一份更新件
myType
具有自连接属性,因此是树结构。
目前,我正在清除整个表,并将更新后的列表保存到数据库中。 既然这样做效率不高,我该如何比较它们并仅将更改保存到我的数据库中?
以下是一个场景:

List<Person> tree1 = new List<Person>();
tree1.Add
    (
        new Person() 
        { 
            Name = "Sr. John", 
            Age = 15, 
            People = new List<Person>() 
            {
                new Person() 
                { 
                    Name="John", 
                    Age=10, 
                    People=null 
                } 
            } 
        }
    );
List tree1=新列表();
树1.添加
(
新人()
{ 
Name=“老约翰”,
年龄=15岁,
人员=新列表()
{
新人()
{ 
Name=“John”,
年龄=10岁,
People=null
} 
} 
}
);

List tree2=新列表();
树2.添加
(
新人()
{ 
Name=“老约翰”,
年龄=15岁,
人员=新列表()
{ 
新人()
{ 
Name=“John”,
年龄=10岁,
人员=新列表()
{
新人()
{
Name=“小约翰”,
年龄=5岁,
People=null
}
} 
} 
} 
}
);

假设您没有对同一个人的多个引用,您可以使用以下算法

它需要
Person
类来实现接口,如果两个对象标识相同的人,则返回
true
:具有相同的
引用
PK(如果在两个树中都填充了它)或
名称
年龄
;但是比较应该忽略孩子(不应该比较
成员)

private static List EmptyList=new List();
作废保存差异(列表树删除、列表树删除)
{
foreach(treenew中的var pers)
{
int index=treeold.IndexOf(pers);
如果(索引>=0)
{//两个列表中都存在节点,请检查chlid节点:
SaveDifference(treeold[index].People,pers.People);
移除树(索引);
}
其他的
{//新添加的节点
//TODO:将“pers”存储到数据库(并更新父级中的引用)
保存差异(EmptyList,pers.People)
}
}
foreach(树中的变量pers)
{//节点已删除
保存差异(pers.People,EmptyList);
//TODO:从数据库中删除“pers”(并更新父级中的引用)
}
}

如何确定两个人是同一个人?你的数据库的模式是什么?我有一个表person,它有一个
Reference
主键字段,还有
Name
Age
以及EF为
Reference\u person
的自加入类生成的另一个字段。我只想说,合并2个以上提到的列表成一个与变化只适用于它。谢谢你的答复。但实际上我不明白它的用途。当我实现
IEquatable
时,它会给我
Equals(键入other)
方法。您能再解释一下吗?
SaveDifference
上面的方法使用
IndexOf
方法从“旧”列表中的“新”列表中查找一个人。
IndexOf
方法使用
EqualityComparer.Default
(请参见MSDN),然后使用
IEquatable.Equals
确定列表中的两个给定对象是否代表同一个人。F.i.,在示例代码中,您创建了两个不同的
Sr.John
实例,因此默认方法将比较引用并返回false。因此,您必须提供
Equals
方法来比较唯一标识个人的字段(例如
Name
field)。
List<Person> tree2 = new List<Person>();
tree2.Add
    (
        new Person() 
        { 
            Name = "Sr. John", 
            Age = 15, 
            People = new List<Person>() 
            { 
                new Person() 
                { 
                    Name = "John", 
                    Age = 10, 
                    People = new List<Person>()
                    {
                        new Person()
                        {
                            Name = "Jr. John",
                            Age = 5,
                            People = null
                        }
                    } 
                } 
            } 
        }
    );
private static List<Person> EmptyList = new List<Person>();
void SaveDifference(List<Person> treeold, List<Person> treenew)
{
    foreach(var pers in treenew)
    {
        int index = treeold.IndexOf(pers);
        if(index >= 0)
        {   // node exists in both lists, check chlid nodes:
            SaveDifference(treeold[index].People, pers.People);
            treeold.RemoveAt(index);
        }
        else
        {   // new added node
            // TODO: Store 'pers' to database (and update references in parent)
            SaveDifferences(EmptyList, pers.People)
        }
    }

    foreach(var pers in treeold)
    {   // node was deleted
        SaveDifferences(pers.People, EmptyList);
        // TODO: remove 'pers' from DB (and update references in parent)
    }
}