Как я могу получить содержимое пользовательских типов в запросе 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, и это кажется слишком сложным для моих целей. Может ли Орчард сделать это за меньшее количество шагов?

0 ответов

Другие вопросы по тегам