以下是我固定的投影頁面的問題,但是相同的方法或更簡單的方法可以應用於您的案例。
在爲Content
形狀投影頁面,Content-ProjectionPage.cshtml
的備用模板,我做了以下,這對媒體表示,項目將在將來使用創建一個查詢:
// Pre-fetch images
var projectionItems = ((IEnumerable<dynamic>)
((IEnumerable<dynamic>)Model.Content.Items)
.First(i => i.Metadata.Type == "List").Items)
.Select(s => (ContentItem)s.ContentItem);
var mediaLibraryFields = projectionItems
.SelectMany(i => i.Parts.SelectMany(p => p.Fields.Where(f => f is MediaLibraryPickerField)))
.Cast<MediaLibraryPickerField>();
var firstMediaIds = mediaLibraryFields
.Select(f => f.Ids.FirstOrDefault())
.Where(id => id != default(int))
.Distinct()
.ToArray();
var firstMedia = WorkContext.Resolve<IContentManager>()
.GetMany<MediaPart>(firstMediaIds, VersionOptions.Published, QueryHints.Empty);
var mediaCache = Layout.MediaCache == null
? Layout.MediaCache = new Dictionary<int, MediaPart>()
: (Dictionary<int, MediaPart>) Layout.MediaCache;
foreach (var media in firstMedia) {
mediaCache.Add(media.Id, media);
}
在你的情況,因爲您可以直接訪問它們,所以無需對形狀進行復雜的挖掘以挖掘字段。我必須這樣做,因爲視圖或形狀表提供者不幸是我做這件事最容易的地方。
然後,當我想要顯示圖像時,我所要做的就是訪問我的查找並嘗試從那裏獲取它。在我的備用模板MediaLibraryPicker.Summary.cshtml
,我這樣做:
var field = (MediaLibraryPickerField)Model.ContentField;
var imageIds = field.Ids;
if (imageIds.Any()) {
var cm = Model.ContentPart.ContentItem.ContentManager as IContentManager;
var title = cm == null || Model.ContentPart == null
? "" : cm.GetItemMetadata(Model.ContentPart).DisplayText;
var mediaCache = Layout.MediaCache as Dictionary<int, MediaPart>;
var firstImage = mediaCache != null
? mediaCache[imageIds.First()]
: cm.Get(imageIds.First()).As<MediaPart>();
<div class="gallery">
<a href="@Url.ItemDisplayUrl((IContent)Model.ContentPart)"><img src="@Display.ResizeMediaUrl(Path: firstImage.MediaUrl, Width: 132)" class="main" alt="@title"/></a>
</div>
}
我只是在顯示領域的第一個圖像,在這裏,但你可以改變它呢f.Ids.FirstOrDefault()
。請改爲f.Ids
,並用SelectMany
替換Select
。還要更改摘要模板,以便在同一字典中查看後顯示所有圖像。
一旦我這樣做,我沒有選擇N + 1,而是獲得頁面上所有圖像的單個SQL查詢。
問題不在於它是一個字段(字段數據存儲在內容項目記錄本身中),而是由該字段鏈接的媒體內容項目不是原始查詢的一部分。 –
@BertrandLeRoy - 有道理。有關我應該怎麼做的任何建議? – joshb
並非如此,但如果您可以預先收集媒體項目的ID,那麼您可以讓GetMany將所有內容重新拼接在一起。但是,我並沒有真正想到這一點,對不起。 –