[英]How to write recursive lambda expression (LINQ query)
我有一個對象:
public class Folder : DBObjectBase
{
public string Name { get; set; }
public List<FileEntry> Files { get; set; }
public Folder ParentFolder { get; set; }
public List<Folder> ChildFolders { get; set; }
}
我編寫了一個查詢,檢索一個文件夾結構以及每個文件夾中的所有文件:
var results = DbContext.Set<Folder>()
.Include(f => f.ParentFolder)
.Include(f => f.ChildFolders)
.Include(f => f.Files)
.Include(f => f.ChildFolders.Select(f1 => f1.Files))
.Include(f => f.ChildFolders.Select(f1 => f1.ChildFolders).Select(f2 => f.Files))
.Include(f => f.ChildFolders.Select(f1 => f1.ChildFolders).Select(f2 => f.ChildFolders.Select(f3 => f3.Files)))
.Include(f => f.ChildFolders.Select(f1 => f1.ChildFolders).Select(f2 => f.ChildFolders.Select(f3 => f3.ChildFolders.Select(f4 => f4.Files))))
.Include(f => f.ChildFolders.Select(f1 => f1.ChildFolders).Select(f2 => f.ChildFolders.Select(f3 => f3.ChildFolders.Select(f4 => f4.ChildFolders.Select(f5 => f5.Files)))))
.Include(f => f.ChildFolders.Select(f1 => f1.ChildFolders).Select(f2 => f.ChildFolders.Select(f3 => f3.ChildFolders.Select(f4 => f4.ChildFolders.Select(f5 => f5.ChildFolders.Select(f6 => f6.Files))))))
.Where(f => f.ParentFolder == null);
上面的代碼恰好返回了我所需要的,但是我不喜歡代碼,如果我想在文件夾結構中添加更多的層,則會導致問題。
有什么想法可以寫這個,所以我得到所有的Child文件夾,以及所有文件,盡管我的文件夾結構中有多少層?
遺憾的是,LINQ AFAIK中沒有遞歸支持(我遇到了同樣的問題),但是您至少可以將其縮短為:
var results = DbContext.Set<Folder>()
.Include(f => f.ParentFolder)
.Include(f => f.Files)
.Include(f => f.ChildFolders.Select(f1 => f1.ChildFolders).Select(f2 => f.ChildFolders.Select(f3 => f3.ChildFolders.Select(f4 => f4.ChildFolders.Select(f5 => f5.ChildFolders.Select(f6 => f6.Files))))))
.Where(f.ParentFolder == null);
如果選擇“較高級別”,則還將包括所有“較低級別”。
我認為這是因為SQL也對此不提供支持。
如果您可以使用對數據庫的多個查詢來執行此“代碼”(或者完全不使用數據庫),請參閱golergka的注釋。
您有一棵文件夾樹,並且想要遞歸查找所有文件。 這可以使用深度優先搜索之類的算法來完成:
public static IEnumerable<FileEntry> GetAllFiles(Folder folder)
{
foreach(var file in folder.Files)
{
yield return file;
}
foreach(var nestedFolder in folder.ChildFolders)
{
foreach(var file in GetAllFiles(nestedFolder))
{
yield return file;
}
}
}
在C#中這不是很漂亮,因為它不支持產生多個結果,但是可以工作。 另外,如果您有大量文件或非常嵌套的文件夾,則可能需要使用更有效的技術(例如Queue
)來實現此算法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.