首页 > 解决方案 > Umbraco 7.3 - 查找 DocumentTypeAlias 的所有子项,而无需使用 LINQ

问题描述

我有一个非常基本的例子:

string areaType = "PrivateHomes";

var plotProperties = Model.Content.AncestorOrSelf(1)
    .Children.Where(c => c.DocumentTypeAlias.Equals("Properties")).First()
    .Children.Where(c => c.Name == areaType).First()
    .Children.First()
    .Children.First();

foreach(var child in plotProperties.Children())
{ /* Do stuff */ }

这段代码似乎......适得其反......不知何故......我的目标是让 DocumentType “Types” 的孩子有一个名为“PrivateHomes”的孩子 - 有没有办法在不做我在这里做的事情的情况下实现这一目标?上面的代码正在运行,但我无法评估它的影响。

标签: c#asp.netumbracoumbraco7

解决方案


有很多选择,但这里有一些有趣的选择,不分先后。

选项 1:TypedContentAtXPath
我真的很喜欢这种方法。这是我在 Umbraco 7 中的首选。在 Umbraco 7 中,发布的内容被缓存为 xml。您可以探索 xml/App_Data/umbraco.config以了解其形状。你也可以像这样使用 XPATH 查询它:

var privateHomesNode = Umbraco.TypedContentSingleAtXPath("//Properties/*[@nodeName='PrivateHomes'");

选项 2:XPathNavigator
这个选项写起来没那么有趣,但运行得非常快。当我的目标是检索一个值而不是整个模型时,我喜欢偶尔使用这个选项。

var navigator = UmbracoContext.Current.ContentCache.GetXPathNavigator();
var privateHomesExpression = navigator.Compile("root//Properties//*[@nodeName='PrivateHomes']");
var firstPrivateHome = navigator.SelectSingleNode(privateHomesExpression);
var firstPrivateHomeId = firstPrivateHome?.GetAttribute("id", "")

选项 3:UmbracoHelper 上的类似 Linq 的扩展
这是您尝试的选项。有很多不同的方法可以做到这些。如果您使用的是 ModelsBuilder,您也可以在查询中使用强类型模型。你可以使用.Descendants(),但你必须非常小心。它可以很快变成一个代价高昂的查询。您可能会花费大量时间IPublishedContent从您甚至不关心检索的数据中构建模型。

var privateHomesNode = Model.Content.AncestorOrSelf(1)
    .Children<CategoryPage>().First()
    .Children.First(c => c.Name == "PrivateHomes");

选项4:查询查询 查询查询
的方法有很多。您可以执行简单的 TypedSearch 之类的操作Umbraco.TypedSearch("PrivateHomes"),但这可能会返回您不想要的结果。你可以像这样做一些更复杂的事情:

var externalSearcher = ExamineManager.Instance.SearchProviderCollection["externalSearcher"];
var searchCriteria = _internalSearcher.CreateSearchCriteria();
var query = searchCriteria.RawQuery("nodeName:PrivateHomes");
var results = _internalSearcher.Search(query);

您要避免的最重要的事情是.Descendants()在可以提供帮助的情况下使用。我们在 2017 年对查询内容的不同方式进行了一些基准测试。这不是非常彻底,但我们的一项发现是使用.Descendants()如下查询可能会非常慢:Model.Content.AncestorOrSelf(1).DescendantsOrSelf().Where(c => c.IsDocumentType("myDocType")). 当我们重复运行上述查询时,结果会更好,因为 Umbraco 最终会将结果缓存在内存中。我们发现通过 XPath 进行查询Umbraco.TypedContentAtXPath("//myDocType")不会遇到第一次初始缓慢加载。我相信这是因为 XPath 查询不会花费时间IPublishedContent从所有中间结果中构建模型。


推荐阅读