从给定文件路径字符串中获取最后一个文件夹的ID,以充当正在创建的新文件夹的父ID

问题描述 投票:0回答:2

我有文件夹对象存储方式,我可以看到哪个文件夹在哪个文件夹中。这些对象有idnameparentIdattributes。每个文件夹的parentId是另一个文件夹的id。根文件夹的父ID为空。

我有一个允许创建新文件夹的表单。该表单采用name(字符串)和parent(字符串)输入。名称可以是任何名称,但父级必须采用现有文件夹的格式:"Documents|Books|Fiction"等。如果尚未存在文件夹,则要创建初始Documents文件夹,父级可以为空。

我正在努力寻找算法,以确保在给定父文件路径的情况下将新文件夹映射到正确的文件夹中。例如,如果文件夹结构如下所示:

Documents|Holidays

Documents|Books|Holidays

Documents|Jobs|Books|Holidays

并且假设我正在使用name "My Day in Paris"parent "Documents|Books|Holidays"创建一个新文件夹在CreateFolder的控制器方法中,在我将新的Folder对象保存到数据库之前,我需要将此Folder对象赋予父文件夹的ParentId。在我们的例子中,父是Holidays文件夹,其路径为"Documents|Books|Holidays"

例如,我可以查询数据库(伪代码):db.Folders.where(x => x.Name == "Holidays").Select(y => y.Id).single();但是这不会从文件路径中找到正确的文件夹来设置正确的ParentId。

如何以这种方式获得父ID?我试着搜索了几年,试图找出算法,但没有运气。

我自己尝试更新。它返回正确的值以返回,但它不会返回此值,而是继续返回先前暂停的递归周期。如何在不退回的情况下打破输出值?

public int GetIdFromPath(string path)
        {
            int _parentId = 0;
            var folderStructure = GetFolderStructure();

            if (path != null)
            {
                _parentId = recursiveFunction(path, folderStructure);
                return _parentId;
            }

            return _parentId;
        }

        private int recursiveFunction(string path, List<Folder> folders)
        {
            var splitPath = path.Split('|');
            var _parentId = 0;
            foreach (var item in splitPath)
            {
                try
                {
                    foreach (var folder in folders)
                    {
                        if (folder.Name == item)
                        {
                            splitPath = splitPath.Where(x => x != item).ToArray();
                            _parentId = folder.Id;

                            if (splitPath.Count() > 0)
                            {
                                var newPath = string.Join("|", splitPath);
                                recursiveFunction(newPath, folder.FolderBookmarks.OfType<Folder>().ToList());
                            }

                            return _parentId;
                        }
                    }
                }
                catch (Exception e)
                {
                    return _parentId;
                }
            }

            return _parentId;
        }

        public List<Folder> GetFolders()
        {
            var folders = db.Bookmarks.OfType<Folder>().ToList();
            return folders;
        }

        public List<Folder> GetFolderStructure()
        {
            var folders = GetFolders();

            foreach (var folder in folders)
            {
                var bookmarks = db.Bookmarks.Where(x => x.ParentId == folder.Id).ToList();
                folder.FolderBookmarks = bookmarks;
            }

            return folders;
        }
c# asp.net-mvc algorithm linq
2个回答
1
投票

您必须像这样逐步找到每个父项,并处理异常:

int? _parentId = null;
foreach (var item in path.Split('|'))
{
    var folder = db.Folders
                    .where(x => x.Name == item&&x.ParentId = _parentId)
                    .Select(y => y.Id)
                    .Single();
    _parentId = folder.Id;
}
return _parentId;

0
投票

我想出了解决方案。变量folders是文件夹对象的列表。 (注意:文件夹有很多文件夹)。下面的代码将父ID设置为与路径名匹配的文件夹名称的文件夹ID。然后将文件夹列表设置为该文件夹的内部文件夹列表;这将允许在文件夹中查看。 (另请注意,我们不允许在此上下文中使用重复的文件夹名称)。谢谢Reza,你的评论有帮助!

public int GetParentIdFromPath(string path)
    {
        int _parentId = 0;

        if (path != null)
        {
            var folders = GetFolderStructure();
            var splitPath = path.Split('|');

            foreach (var item in splitPath)
            {
                _parentId = folders.Where(x => x.Name == item).SingleOrDefault().Id;
                folders = folders.Where(x => x.Name == item).SingleOrDefault().FolderBookmarks.OfType<Folder>().ToList();
            }

            return _parentId;
        }

        return _parentId;
    }
© www.soinside.com 2019 - 2024. All rights reserved.