我有一些文件夹对象存储方式,我可以看到哪个文件夹在哪个文件夹中。这些对象具有id
,name
和parentId
属性。每个文件夹的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;
}
答案 0 :(得分: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;
答案 1 :(得分: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;
}