How can I eager fetch content of custom types in a ContentManager query?

半世苍凉 提交于 2019-12-11 05:17:58

问题


I'm running into some n+1 performance issues when iterating over a collection of ContentItems of a custom Type that I created solely through migrations.

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

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

Every time I access a field of this part a new query is performed. I can use QueryHints to avoid this for the predefined parts

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

but can I do this for the ContentPart of my custom type too? This does not seem to work:

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

How can I tell Orchard to just get everything in one go? I'd prefer to be able to do this without writing my own HQL or directly addressing the repositories.

Example:

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 doesn't store ids and using the TaxonomyService inside of the loop wouldn't improve performance. Right now, to work around this, I fetch all TermContentItems.Where(x => myItems.Select(i => i.Id).Contains(TermPartRecord.Id)) from the repository outside of the loop as well as a list of all the terms of the Taxonomy that the field is using. Then inside the loop:

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

I'm not a very experienced programmer but this was the only way I could see how to do this without digging into HQL and it seems overly complicated for my purposes. Can Orchard do this in less steps?

来源:https://stackoverflow.com/questions/39203555/how-can-i-eager-fetch-content-of-custom-types-in-a-contentmanager-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!