循环递归自联接表

时间:2014-06-16 10:03:25

标签: c# sql .net sql-server linq

我有以下SQL Server表结构,它是一个逻辑树文件夹结构。

SQL Server Table Structure

我在SQL Server中使用Linq to SQL。

我想要做的是在内存中循环和创建文件夹结构,从Root开始的层级文件夹,所有子项的主要父级。

Folder structure

我试图用一些foreach循环来做这件事,但我仍然没有得到它。我想我必须使用某种递归方式。

我尝试了一些查询:

var flds = from folders in repo.Folders
                                   join folders2 in repo.Folders on folders.Id equals folders2.idParent
                                   select folders;

我的目标是迭代该文件夹逻辑结构。

2 个答案:

答案 0 :(得分:2)

如果要将文件夹作为表中给出的层次结构,可以像这样创建:

    var tableData = repo.Folders.ToList();
    var directories = tableData.Select(f => GetPath(f, table));

正如您所问,创建文件夹层次结构的递归方法是:

    private static string GetPath(Folder f)
    {
        if (f.IdParent == 0)
        {
            return f.Name;
        }
        else
        {
            var parent = tableData.Find(d => d.Id == f.IdParent);
            return GetPath(parent) + "|" + f.Name;
        }
    }

您将获得如下输出:

Output

它会给你一个完整的文件夹hirarchy,我不知道你想如何使用它。所以你可以根据需要做一些修改。希望它有所帮助!

这里我要添加代码来迭代并创建文件夹结构:

        foreach (var dir in directories)
        {
            var folders = dir.Split('|');
            var path = string.Empty;
            foreach (var folder in folders)
            {
                path = path + "\\" + folder;  // modify the path like '\\' if it is not valid I have not tested
                CreateFolder(path); // implement this method for actual creation of folders
            }
        }

您创建文件夹的方法:

private static void CreateFolder(string directory)
    {
        var path = "C:" + directory; // add whenever you want to create structure
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
    }

答案 1 :(得分:1)

你可以尝试这个:

// Get a list of the folders.
// We do this, in order to avoid the performance hit, that Panagiotis 
// pointed out correctly in his comment.
var folders = repo.Folders.ToList();

// Get the root folder.
var rootFolder = folders.Where(x=>x.idParent==null).SingleOrDefault();

// Group the folders by their parentId.
var groupedFolders = from folder in folders
                     where folder.idParent!=null
                     orderby folder.idParent ascending
                     group folder by folder.idParent into grp
                     select new
                     {
                         ParentFolderId = grp.Key,
                         Folders = grp.Select(x=>x)
                     };

// Print the name of the root folder.
Console.WriteLine("Root Folder", rootFolder.Name);

// Iterate through the groups of folders. 
foreach(var grp in groupedFolders)
{
    // Get the name of the parent folder for the current group.
    string parentFolderName = folders.Where(x=>x.Id==grp.ParentFolderId)
                                     .Single(x=>x.Name);


    // Print the name of the parent folder.
    Console.WriteLine("Parent Folder", parentFolderName);

    // Iterate through the folders of the current group.
    foreach(var folder in grp.Folders)
    {
        Console.WriteLine(folder.Name);
    }
}