Как я могу получить содержимое пользовательских типов в запросе ContentManager?
Я сталкиваюсь с некоторыми проблемами с производительностью n+1, когда перебираю коллекцию ContentItems пользовательского Типа, который я создал исключительно путем миграции.
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>()
...
);
Как я могу сказать Орчарду, чтобы все получилось за один раз? Я предпочел бы иметь возможность делать это без написания собственного 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 не хранит идентификаторы, и использование 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, и это кажется слишком сложным для моих целей. Может ли Орчард сделать это за меньшее количество шагов?