0

Umbraco 4.7 で記事をブログにインポートするための C#(.NET) を書いています。つまり、このアルゴリズムは、既存のすべての記事を循環して、XML から取得しようとしている新しい記事と同じ ID を持っているかどうかを確認するように設計されています。アルゴリズムは問題なく動作しますが、4 つの foreach ループを持つことは、私がやっていることに対して非常に非効率的であると思わずにはいられません。

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 ループのみです。特定のノードを含むフォルダー構造に近いため、単にカレンダーの日付を循環するよりも少し複雑です。これを単純化する方法を提案できる人はいますか?

4

1 に答える 1

4

すべての記事ノードをで取得するというアイデアを使用すると、このGetDescendants拡張メソッドDocumentTypeに相当するものを使用して、特定のドキュメントタイプのノードを反復処理できます。

このメソッドは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はXMLキャッシュから情報を取得し、データベースを毎回呼び出す必要がないため、NodeFactoryNodeを使用する方が効率的です。NodeFactoryを使用することの唯一の欠点は、公開されたノードのみが含まれていることですが、通常は、とにかくそれらのノードのみを操作する必要があります。ノードとドキュメントの違いを参照してください。DocumentDocument

編集:少しいじくり回した後、DocumentすでにGetDescendants()メソッドが含まれていて、それがを返すことを発見IEnumerableしました。そのため、を実行する必要があり.Cast<Document>()ます。したがって、を引き続き使用することを選択した場合は、拡張メソッドを作成する必要がないように見えますDocument。それ以外の場合でも、上記の拡張メソッドのようなものを使用する場合は、名前を別の名前に変更する必要があります。

于 2012-07-09T15:26:39.297 に答える