1

在迭代我仅通过迁移创建的自定义类型的 ContentItem 集合时,我遇到了一些 n+1 性能问题。

ContentDefinitionManager.AlterPartDefinition("MyType", part => part
    .WithField("MyField", field => field
        ...
    )
);

ContentDefinitionManager.AlterTypeDefinition("MyType", type => type
    .WithPart("MyType")
);

每次我访问这部分的一个字段时,都会执行一个新查询。对于预定义的部分,我可以使用 QueryHints 来避免这种情况

var myItems = _orchardServices.ContentManager.Query().ForType("MyType")
            .WithQueryHints(new QueryHints().ExpandParts<LocalizationPart()
            ...
);

但是我也可以为我的自定义类型的 ContentPart 执行此操作吗?这似乎不起作用:

var myItems = _orchardServices.ContentManager.Query().ForType("MyType")
            .WithQueryHints(new QueryHints().ExpandParts<ContentPart>()
            ...
);

我如何告诉 Orchard 一口气搞定所有东西?我希望能够在不编写自己的 HQL 或直接寻址存储库的情况下做到这一点。

例子:

var myItems = _orchardServices.ContentManager.Query().ForType("MyType");

@foreach(var item in myItems.Take(100)) {
    foreach(var term in item.Content.MyItem.MyTaxonomyField.Terms) {
        // Executes 100 queries
        <div>@term.Name</div>
    }
}

TaxonomyField 不存储 id,在循环内使用 TaxonomyService 不会提高性能。现在,为了解决这个问题,我TermContentItems.Where(x => myItems.Select(i => i.Id).Contains(TermPartRecord.Id))从循环外部的存储库中获取所有内容,以及该字段正在使用的分类法的所有术语的列表。然后在循环内:

var allTermsInThisField = termContentItems.Where(tci => tci.TermsPartRecord.Id == c.Id)
.Select(tci => terms.Where(t => t.Id == tci.TermRecord.Id).Single()).ToList()

我不是一个非常有经验的程序员,但这是我可以在不深入研究 HQL 的情况下了解如何做到这一点的唯一方法,而且对于我的目的来说它似乎过于复杂。Orchard 能否以更少的步骤完成此任务?

4

0 回答 0