问题描述
在循环中发现自己。我有一个数据库表,该表定义了一个目录文件夹结构,其中子文件夹的数量可能是无限的。
最终结果文件夹结构应如下所示,但逻辑应允许更改此结构要求:
为上述文件夹结构提供此数据:
最重要的字段是id
和pid
。 pid
中的NULL
代表顶级文件夹(电子邮件,TM应用程序,TM争议)。所有其他文件夹都是子文件夹,它们向下存储在level_count
字段中的3个级别中。不确定我是否确实需要level_count
字段。我一直在尝试使逻辑尽可能“灵活”。 pid
定义文件夹的直接父级:
我当前的解决方案还不够好,因为它不能处理“ infinite” 个级别,它仅支持三个级别。我不想不必知道级别数。
如果可能的话,我希望能够保留核心逻辑,并且我不想更改这种方式,即先创建所有父文件夹,然后再返回以创建子文件夹。相反,我想进入最深的层次,创建这些文件夹,然后备份到父母。我认为,如果我有道理,这段代码就代表了这个想法。
foreach (DataRow r in dtParentFolders.Rows) // these are the 3 parent rows with null pid
{
int parentFolderId = Convert.ToInt32(r["id"]);
string parentFolderName = r["folder_name"].ToString();
//Create folder
Console.WriteLine(parentFolderName);
DataTable dt = GetFolders(parentFolderId);
foreach (DataRow r2 in dt.Rows)
{
parentFolderId = Convert.ToInt32(r2["id"]);
CreateFolder(r2);
dt = GetFolders(parentFolderId);
foreach (DataRow r3 in dt.Rows)
{
parentFolderId = Convert.ToInt32(r3["id"]);
CreateFolder(r3);
dt = GetFolders(parentFolderId);
}
}
}
解决方法
我希望这可以在某种程度上帮助您。
public class Record
{
public int Id { get; set; }
public int PId { get; set; }
public string Name { get; set; }
}
public static void Main()
{
var records = new List<Record>()
{
new Record { Id = 1,Name = "MainDir1",PId = 0 },new Record { Id = 2,Name = "MainDir2",new Record { Id = 3,Name = "MainDir3",new Record { Id = 4,Name = "SubDir1",PId = 1 },new Record { Id = 5,Name = "SubDir2",PId = 2 },new Record { Id = 6,Name = "SubSubDir1",PId = 5 },new Record { Id = 7,Name = "SubSubDir2",new Record { Id = 8,Name = "SubSubDir3",new Record { Id = 9,Name = "SubSubDir4",new Record { Id = 10,Name = "SubSubDir5",};
var node = new Directory(0,null,null);
records
.OrderBy(x => x.PId)
.ThenBy(x => x.Id)
.ThenBy(x => x.Name)
.ToList()
.ForEach(x => node.AddChild(x.Name,x.Id,x.PId));
node.Print();
}
public class Directory
{
public Directory(int id,string name,Directory parent)
{
this.Id = id;
this.Name = name;
this.Parent = parent;
this.Indentation = parent is null ? 0 : parent.Indentation + 1;
this.Children = new HashSet<Directory>();
}
public int Id { get; set; }
public int Indentation { get; set; }
public string Name { get; set; }
public Directory Parent { get; set; }
public ICollection<Directory> Children { get; set; }
public void AddChild (string name,int id,int parentId)
{
if (this.Id == parentId)
{
this.Children.Add(new Directory(id,name,this));
return;
}
foreach (var child in this.Children)
{
child.AddChild(name,id,parentId);
}
}
public void Print()
{
Console.WriteLine($"{new string(' ',this.Indentation * 4)}{this.Name}");
foreach (var child in this.Children)
{
child.Print();
}
}
}