2014-05-06 46 views
1

我有一個對象:如何寫遞歸lambda表達式(LINQ查詢)

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); 

上面的回報正是我所需要的,但我不喜歡代碼,如果我想向文件夾結構添加多個圖層,會導致問題。

任何想法,我可以寫這個,所以我得到所有的子文件夾和所有文件,儘管在我的文件夾結構中有多少層?

+2

爲什麼不使用一個好的舊遞歸樹遍歷? –

+1

看看這個:http://stackoverflow.com/questions/61143/recursive-lambda-expression-to-traverse-a-tree-in-c-sharp –

+1

你能澄清一下:你是否在使用數據庫而你想要將其轉換爲一個DB命令? – ChrFin

回答

1

可悲的是在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也有這種不支持...

如果你是罰款「代碼」這個使用多個查詢到數據庫執行(或者您不使用DB在所有)請參閱golergka的評論。

0

你有一個文件夾樹,你想要遞歸地查找所有文件。這可以使用算法,如深度優先搜索來完成:

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)。

+0

懷疑由'DBObjectBase'所以他想,他是使用DB後端不通過代碼來做到這一點... – ChrFin