2012-07-09 43 views
0

我正在編寫一些C#(.NET)與Umbraco 4.7一起使用以將文章導入到博客中。簡而言之,這種算法被設計用於遍歷每一篇現有文章,並檢查它是否與我們試圖從XML中引入的新文章具有相同的ID。該算法工作正常,但我不禁覺得有四個foreach循環對我所做的事情來說效率非常低。檢查樹形結構中的每個節點,使用Umbraco(提高效率)

foreach (Document yearNode in node.Children) //News > Years 
{ 
    foreach (Document monthNode in yearNode.Children) //Years > Months 
    { 
     foreach (Document dayNode in monthNode.Children) //Months > Days 
     { 
      foreach (Document newsItem in dayNode.Children) //Days > Articles 
      { 
       // If there isn't an ID match, go ahead and create a new article node.   
      } 

這是沒有它的主要功能的基本算法,只是foreach循環。這比簡單地循環日曆日期要複雜一些,因爲它更像是包含特定節點的文件夾結構。任何人都可以建議一種簡化這一點的方法嗎?

+0

Umbraco特定類型上方的'Document'類型? – reuben 2012-07-09 08:56:27

+0

是的,是的。作爲BusinessLogic的一部分,[鏈接](http://our.umbraco.org/wiki/reference/api-cheatsheet/creating-a-document) – edparry 2012-07-09 09:01:20

+0

您可以建立文檔文件夾結構的緩存,並執行在緩存中快速查找? – reuben 2012-07-09 09:12:54

回答

4

使用通過DocumentType獲取所有文章節點的想法,您可以使用等效的this GetDescendants extension method來遍歷特定文檔類型的節點。

該方法是專門爲NodeFactory的Node類編寫的,但可以很容易地被重寫爲Document。要使用擴展方法,您需要創建一個新類並將其設爲靜態。例如:

using System; 
using System.Collections.Generic; 
using umbraco.cms.businesslogic.web; 

namespace Example 
{ 
    static class Extensions 
    { 
     public static IEnumerable<Document> GetDescendants(this Document document) 
     { 
      foreach (Document child in document.Children) 
      { 
       yield return child; 

       foreach (Document grandChild in child.GetDescendants()) 
       { 
        yield return grandChild; 
       } 
      } 
      yield break; 
     } 
    } 
} 

再使用的方法在我們的語境:

var myDocuments = new Document(folderId) 
    .GetDescendants() 
    .Cast<Document>() 
    .Where(d => d.ContentType.Alias == "myDocumentType"); 

if (myDocuments.Any(d => d.Id == myId)) 
{ 
    ... 
} 

注:我不知道爲什麼,但它似乎是一個.OfType<Document>().Cast<Document>().GetDescendants()後需要。 (見下文編輯)

這將是更有效地使用NodeFactory的Node而不是Document因爲NodeFactory拉它從XML緩存信息,不會對數據庫每次像Document不來電。使用NodeFactory的唯一缺點是它只包含那些已經發布的節點,但通常你只想用這些節點。見Difference between Node and Document

編輯:做一個小的修修補補之後,我發現Document已經包括GetDescendants()方法返回一個IEnumerable,這就是爲什麼我們要做的.Cast<Document>()。因此,如果您選擇仍使用Document,則您可以避免創建擴展方法。否則,如果您仍想使用上述擴展方法之類的東西,則需要將其重命名爲其他內容。

+1

+1 dludlow的另一個很好的答案。幹得好,繼續保持下去。 – 2012-07-09 17:11:17

+0

我不得不同意@GoranMottram,非常感謝你! – edparry 2012-07-10 07:58:56