对象树
Tree of objects
我有这个包含 2000 多个类别的列表,在发送到控制器和视图之前需要将它们组织成树状,以便 javascript 插件可以正确呈现它们。
我已经在这样做了,但是性能很糟糕。 assemble 树大约需要 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;
}
}
我认为问题出在新实例上并尝试使用并行循环但没有令人满意的改进。
现在是使用哈希表(字典)的好时机。像下面的代码应该有所帮助。
// 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 将包含对根元素(没有父级的类别)的直接引用,假设您的数据是以这种方式构建的。
我有这个包含 2000 多个类别的列表,在发送到控制器和视图之前需要将它们组织成树状,以便 javascript 插件可以正确呈现它们。
我已经在这样做了,但是性能很糟糕。 assemble 树大约需要 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;
}
}
我认为问题出在新实例上并尝试使用并行循环但没有令人满意的改进。
现在是使用哈希表(字典)的好时机。像下面的代码应该有所帮助。
// 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 将包含对根元素(没有父级的类别)的直接引用,假设您的数据是以这种方式构建的。