对象树

时间:2015-11-25 11:07:51

标签: c# performance recursion tree hierarchy

我有一个2000多个类别的列表,需要在发送到控制器和View之前在树中组织,以便javascript插件可以正确地呈现它们。

我已经这样做,但表现很糟糕。组装树需要30秒钟。

我无法看到这里的性能下降。你能帮助我改进这段代码吗?

var allCategories = dal.Listar();
List<Model.Entity.CategoriaCursoEADVO> nestedCategories = new List<Model.Entity.CategoriaCursoEADVO>();

foreach (Model.Entity.CategoriaCursoEAD item in allCategories)
{
    if (item.IdCategoriaPai == null)
    {
        CategoriaCursoEADVO child = new CategoriaCursoEADVO();

        child.id = item.Id;
        child.text = item.Descricao;
        nestedCategories.Add(child);
        FillChild(allCategories, child, item.Id);
    }
}

这是FillChild方法:

public int FillChild(IEnumerable<CategoriaCursoEAD> categorias, CategoriaCursoEADVO parent, int IID)
{
    var childCategories = categorias.Where(w => w.IdCategoriaPai.Equals(IID));
    parent.children = new List<CategoriaCursoEADVO>();

    if (childCategories.Count() > 0)
    {
        foreach (CategoriaCursoEAD cat in childCategories)
        {
            CategoriaCursoEADVO child = new CategoriaCursoEADVO();

            child.id = cat.Id;
            child.text = cat.Descricao;
            parent.children.Add(child);
            FillChild(categorias, child, cat.Id);
        }
        return 0;
    }
    else
    {
        return 0;
    }
}

我认为问题出在新实例上,尝试使用并行循环而没有令人满意的改进程度。

1 个答案:

答案 0 :(得分:1)

这是使用HashTable(Dictionary)的好时机。像下面的代码应该有所帮助。

    // Convert the flat list into a hash table with the ID
    // of the element as the key
    var dict = allCategories.ToDictionary (i => i.Id);

    // Group categories by the parent id
    var parentGrouping = allCategories.Where(c => c.IdCategoriaPai != null).GroupBy(c => c.ParentId);

    // Since we group the items by parent id, we can find
    // the parent by id in the dictionary and add the children
    // that have that particular id.
    foreach(var groupItem in parentGrouping)
        if(groupItem.Key != null)
            dict[(int)groupItem.Key].children.AddRange(groupItem);

    // Get the root elements.
    var hierarchicalCategories = allCategories.Where(item => item.IdCategoriaPai == null);

    // Do what you need to do here.

此代码将创建一个类别树。 hierarchicalCategories将包含对根元素(没有父元素的类别)的直接引用,假设您的数据是以这种方式构建的。