2013-02-25 53 views
2

我的任务是将功能添加到现有的代码库中。代码主要由刚离开我们团队的开发人员编写。考虑到这一点,我有一些限制:/。用C#管理人造树#

开发人员之前编写了一些代码,看起来像列表和树之间的交叉。在用户界面中,它是一个树形结构。但是,在代码中,它是一个List。它有点奇怪。两个主要的类定义如下:

public class TreeBranch 
{ 
    public Guid ID { get; set; } 
} 

public class TreeItem 
{ 
    public Guid ID { get; set; } 
    public Guid TreeBranchID { get; set; } 
    public Guid? ParentTreeItemID { get; set; } 

    public int Level { get; set; } 

    public DateTime CreatedOn { get; set; } 
    public DateTime? MarkedOn { get; set; } 
} 

所以,TreeBranch被存储在数据库中的表和TreeItem存储在数据库表中。执行一个查询,该查询返回所有TreeItem元素的特定TreeBranchID,其MarkedOn值为NULL。这是处理列表这样的:

List<TreeItem> treeItems = GetTreeBranchItems("someID"); 
treeItems.Sory(new TreeItemComparer()); 

我TreeItemComparer类如下所示:

public class TreeItemComparer: IComparer<TreeItem> 
{ 
    // allow us to look up parent Items by GUID 
    IDictionary<Guid, TreeItem> itemLookup; 

    public TreeItemComparer(IEnumerable<TreeItem> list) 
    { 
    itemLookup = list.ToDictionary(item => item.ID); 
    foreach (var item in list) 
     SetLevel(item); 
    } 

    public int SetLevel(TreeItem item) 
    { 
    if ((item.Level == 0) && (item.ParentTreeItemID != Guid.Empty)) 
    { 
     if (itemLookup.ContainsKey(item.ParentTreeItemID)) 
     item.Level = 1 + SetLevel(itemLookup[item.ParentTreeItemID]); 
    } 
    else if (item.ParentTreeItemID == Guid.Empty) 
     item.Level = 1; 

    return item.Level; 
    } 

    public int Compare(TreeItem x, TreeItem y) 
    { 
    // see if x is a child of y 
    while (x.Level > y.Level) 
    { 
     if ((x.ParentTreeItemID == y.ID) || (x.ParentTreeItemID == Guid.Empty)) 
     return 1; 
     x = itemLookup[x.ParentTreeItemID]; 
    } 

    // see if y is a child of x 
    while (y.Level > x.Level) 
    { 
     if ((y.ParentTreeItemID == x.ID) || (y.ParentTreeItemID == Guid.Empty)) 
     return -1; 
    } 

    // x and y are not parent-child, so find common ancestor 
    while (x.ParentTreeItemID != y.ParentTreeItemID) 
    { 
     if (x.ParentTreeItemID != Guid.Empty) 
     x = itemLookup[x.ParentTreeItemID]; 
     if (y.ParentTreeItemID != Guid.Empty) 
     y = itemLookup[y.ParentTreeItemID]; 
    } 

    // compare createDate of children of common ancestor 
    return x.CreatedOn.CompareTo(y.CreatedOn); 
    } 
} 

此代码的工作,但有一个例外。偶尔,我会得到一棵破碎的树。举例来说,如果我有一个类似如下结构:

Item 1 
    Item 1-A (Imagine this TreeItem has a MarkedOn value that is NOT null) 
    Item 1-A-a 
     Item 1-A-a-1 
    Item 1-A-b 
    Item 1-B 

好了,在上面的例子中,我只是真的应该具备以下条件:

Item 1 
    Item 1-B 

但是,我越来越

Item 1 
    Item 1-A-a 
    Item 1-A-a-1 
    Item 1-A-b 
    Item 1-B 

我的问题是,具有MarkedOn值的TreeItem和其所有的“children”不应该是集合的一部分。因为我们的环境,我不能碰数据库:(。与此同时,我不知道如何在代码中做到这一点。没有人有任何想法?

谢谢!

+3

我没有看到MarkedOn依赖任何逻辑。既然你说的那个特定的代码位是什么打破,这将有助于将其列入。 – Guvante 2013-02-25 15:44:16

回答

0

你你让他们从数据库返回后可以过滤搜索结果。

List<TreeItem> orphanedItems = new List<TreeItem>(); 
foreach (TreeItem item in results) 
{ 
    if (item.ParentTreeItemID != Guid.Empty && 
     !results.Any(tree => tree.ID == item.ParentTreeItemID) 
    { 
     orphanedItems.Add(item); 
    } 
} 
foreach (TreeItem orphan in orphanedItems) 
    results.Remove(orphan); 
+0

你可以请解释一行“!results.Contains(tree - > tree.ID == item.ParentTreeItemID)”。我得到一个编译时错误。我以为你可能正在尝试lambda运算符在pla “ - >”然而,我也遇到了编译时错误。 – 2013-02-25 17:55:55

+0

@EelsFan:对于很多F#编程,我会解决它。 – Guvante 2013-02-25 18:02:42