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