Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查树状结构中的每个节点,Umbraco(提高效率)_C#_Algorithm_Foreach_Umbraco - Fatal编程技术网

C# 检查树状结构中的每个节点,Umbraco(提高效率)

C# 检查树状结构中的每个节点,Umbraco(提高效率),c#,algorithm,foreach,umbraco,C#,Algorithm,Foreach,Umbraco,我正在编写一些C#(.NET)来与Umbraco 4.7合作,将文章导入博客。简而言之,此算法旨在循环浏览所有现有文章,并检查它是否与我们试图从XML中获取的新文章具有相同的ID。该算法工作正常,但我忍不住认为有四个foreach循环对于我正在做的事情来说是非常低效的 foreach (Document yearNode in node.Children) //News > Years { foreach (Document monthNode in yearNode.Childr

我正在编写一些C#(.NET)来与Umbraco 4.7合作,将文章导入博客。简而言之,此算法旨在循环浏览所有现有文章,并检查它是否与我们试图从XML中获取的新文章具有相同的ID。该算法工作正常,但我忍不住认为有四个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循环。它比简单地循环日历日期要复杂一些,因为它更像是包含特定节点的文件夹结构。有人能提出一种简化的方法吗

使用通过
DocumentType
获取所有文章节点的想法,您可以使用的等价物来迭代特定文档类型的节点

该方法是专门为NodeFactory的
节点
类编写的,但可以轻松地为
文档
重写。要使用扩展方法,您需要创建一个新类并使其成为静态的。例如:

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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用umbraco.cms.businesslogic.web;
名称空间示例
{
静态类扩展
{
公共静态IEnumerable GetSubstands(此文档)
{
foreach(Document.Children中的文档子级)
{
退换子女;
foreach(在child.getsubstands()中记录孙子)
{
收益回报孙子;
}
}
屈服断裂;
}
}
}
然后在我们的上下文中使用该方法:

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

if (myDocuments.Any(d => d.Id == myId))
{
    ...
}
var myDocuments=新文档(folderId)
.gets()
.Cast()
。其中(d=>d.ContentType.Alias==“myDocumentType”);
if(myDocuments.Any(d=>d.Id==myId))
{
...
}
注意:我不知道为什么,但似乎在
.getsubjects()
之后需要
.OfType()
.Cast()
。(请参见下面的编辑)

使用NodeFactory的
节点
比使用
文档
更有效,因为NodeFactory从XML缓存中提取其信息,并且不像
文档
那样每次调用数据库。使用NodeFactory的唯一缺点是它只包含那些已发布的节点,但通常您只希望使用这些节点。看


Edit:在做了一些修改之后,我发现
Document
已经包含了一个
getsubstands()
方法,该方法返回一个
IEnumerable
,这就是为什么我们必须执行
.Cast()
。因此,如果您选择仍然使用
文档
,似乎可以避免创建扩展方法。否则,如果您仍然希望使用类似于上述扩展方法的方法,则需要将其重命名为其他方法。

使用通过
DocumentType
获取所有文章节点的想法,您可以使用的等效方法来迭代特定文档类型的节点

该方法是专门为NodeFactory的
节点
类编写的,但可以轻松地为
文档
重写。要使用扩展方法,您需要创建一个新类并使其成为静态的。例如:

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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用umbraco.cms.businesslogic.web;
名称空间示例
{
静态类扩展
{
公共静态IEnumerable GetSubstands(此文档)
{
foreach(Document.Children中的文档子级)
{
退换子女;
foreach(在child.getsubstands()中记录孙子)
{
收益回报孙子;
}
}
屈服断裂;
}
}
}
然后在我们的上下文中使用该方法:

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

if (myDocuments.Any(d => d.Id == myId))
{
    ...
}
var myDocuments=新文档(folderId)
.gets()
.Cast()
。其中(d=>d.ContentType.Alias==“myDocumentType”);
if(myDocuments.Any(d=>d.Id==myId))
{
...
}
注意:我不知道为什么,但似乎在
.getsubjects()
之后需要
.OfType()
.Cast()
。(请参见下面的编辑)

使用NodeFactory的
节点
比使用
文档
更有效,因为NodeFactory从XML缓存中提取其信息,并且不像
文档
那样每次调用数据库。使用NodeFactory的唯一缺点是它只包含那些已发布的节点,但通常您只希望使用这些节点。看


Edit:在做了一些修改之后,我发现
Document
已经包含了一个
getsubstands()
方法,该方法返回一个
IEnumerable
,这就是为什么我们必须执行
.Cast()
。因此,如果您选择仍然使用
文档
,似乎可以避免创建扩展方法。否则,如果您仍要使用类似上述扩展方法的内容,则需要将其重命名为其他内容。

文档的
类型是否高于Umbraco特定类型?是的。作为业务逻辑的一部分,您是否有可能建立文档文件夹结构的缓存,并在缓存中执行快速查找?如何检索根节点(
节点
)?也许你可以通过它们的
文档类型查询叶节点
?谢谢,@MarkusJarderot,但是你能再解释一下你的意思吗?第一次使用Umbraco和C#,感觉一切都是一个节点!
文档
类型是否高于Umbraco特定类型?是的。业务的一部分