mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
localizationpartdriver refactor (#8366)
* Performance on LocalizationPart Prevent driver from repeating the same query several times in a request (it used to try and fetch all of a part's localizations at least twice per request). Changed query for a MasterContentItem's localizations so it should "hint" sql to use different indexes.
This commit is contained in:
committed by
GitHub
parent
8a327cf887
commit
9d1267a94c
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
@@ -18,6 +19,9 @@ namespace Orchard.Localization.Drivers {
|
||||
_cultureManager = cultureManager;
|
||||
_localizationService = localizationService;
|
||||
_contentManager = contentManager;
|
||||
|
||||
publishedLocalizations = new Dictionary<int, IEnumerable<LocalizationPart>>();
|
||||
latestLocalizations = new Dictionary<int, IEnumerable<LocalizationPart>>();
|
||||
}
|
||||
|
||||
protected override DriverResult Display(LocalizationPart part, string displayType, dynamic shapeHelper) {
|
||||
@@ -69,10 +73,14 @@ namespace Orchard.Localization.Drivers {
|
||||
|
||||
protected override DriverResult Editor(LocalizationPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var model = new EditLocalizationViewModel();
|
||||
|
||||
// GetCulture(part) is checked against null value, because the content culture has to be set only if it's not set already.
|
||||
// model.SelectedCulture is checked against null value, because the editor group may not contain LocalizationPart when the content item is saved for the first time.
|
||||
if (updater != null && updater.TryUpdateModel(model, TemplatePrefix, null, null) && GetCulture(part) == null && !string.IsNullOrEmpty(model.SelectedCulture)) {
|
||||
if (updater != null && updater.TryUpdateModel(model, TemplatePrefix, null, null)
|
||||
// GetCulture(part) is checked against null value, because the content
|
||||
// culture has to be set only if it's not set already.
|
||||
&& GetCulture(part) == null
|
||||
// model.SelectedCulture is checked against null value, because the editor
|
||||
// group may not contain LocalizationPart when the content item is saved for
|
||||
// the first time.
|
||||
&& !string.IsNullOrEmpty(model.SelectedCulture)) {
|
||||
_localizationService.SetContentCulture(part, model.SelectedCulture);
|
||||
}
|
||||
|
||||
@@ -98,16 +106,52 @@ namespace Orchard.Localization.Drivers {
|
||||
return part.Culture != null ? part.Culture.Culture : null;
|
||||
}
|
||||
|
||||
private IEnumerable<LocalizationPart> GetDisplayLocalizations(LocalizationPart part, VersionOptions versionOptions) {
|
||||
return _localizationService.GetLocalizations(part.ContentItem, versionOptions)
|
||||
.Where(c => c.Culture != null)
|
||||
.ToList();
|
||||
private Dictionary<int, IEnumerable<LocalizationPart>> publishedLocalizations;
|
||||
private Dictionary<int, IEnumerable<LocalizationPart>> latestLocalizations;
|
||||
private IEnumerable<LocalizationPart> GetDisplayLocalizations(
|
||||
LocalizationPart part, VersionOptions versionOptions) {
|
||||
|
||||
Func<IEnumerable<LocalizationPart>> actualMethod = () =>
|
||||
_localizationService.GetLocalizations(part.ContentItem, versionOptions)
|
||||
.Where(c => c.Culture != null)
|
||||
.ToList();
|
||||
// if the part has no assigned culture, and it does not belong to
|
||||
// a translation group, it cannot possibly have localizations
|
||||
if (GetCulture(part) == null && !part.HasTranslationGroup) {
|
||||
actualMethod = () => Enumerable.Empty<LocalizationPart>();
|
||||
// this empty list will be "cached" for the part for the duration
|
||||
// a request, in order to prevent asking the db to return something
|
||||
// that we know to not be there. This should prevent a class of
|
||||
// deadlocks on the indexes for the LocalizationPartRecord table.
|
||||
// The reasoning:
|
||||
// part.HasTranslationGroup is false when the content is not a
|
||||
// localization of any other content. It may be a MasterContent,
|
||||
// but if that were the case it would have a value for its Culture.
|
||||
// The condition here represents a new ContentItem, that has never
|
||||
// had an assigned culture (whether it's actually new, or the
|
||||
// LocalizationPart has just been welded to its type)
|
||||
}
|
||||
|
||||
if (versionOptions.IsPublished) {
|
||||
if (!publishedLocalizations.ContainsKey(part.Id)) {
|
||||
publishedLocalizations.Add(
|
||||
part.Id,
|
||||
actualMethod());
|
||||
}
|
||||
return publishedLocalizations[part.Id];
|
||||
} else if (versionOptions.IsLatest) {
|
||||
if (!latestLocalizations.ContainsKey(part.Id)) {
|
||||
latestLocalizations.Add(
|
||||
part.Id,
|
||||
actualMethod());
|
||||
}
|
||||
return latestLocalizations[part.Id];
|
||||
}
|
||||
return actualMethod();
|
||||
}
|
||||
|
||||
private IEnumerable<LocalizationPart> GetEditorLocalizations(LocalizationPart part) {
|
||||
return _localizationService.GetLocalizations(part.ContentItem, VersionOptions.Latest)
|
||||
.Where(c => c.Culture != null)
|
||||
.ToList();
|
||||
return GetDisplayLocalizations(part, VersionOptions.Latest);
|
||||
}
|
||||
|
||||
protected override void Importing(LocalizationPart part, ImportContentContext context) {
|
||||
|
||||
Reference in New Issue
Block a user