我已经实现了一个on item:根据我在这里发布的这个问题保存了处理程序:Run code when Publishing Restriction is saved in Sitecore
当作者更改页面上的发布限制时,我会遍历该页面的每个相关组件,更新每个组件的发布限制以匹配页面项目。这是有效的,但有些页面有150个左右的组件,每个页面的编辑过程都是永远的。结果是UI在运行时最多挂起5分钟。不好。
我这样做:
compItem.Editing.BeginEdit();
compItem.Publishing.ValidFrom = pageItem.Publishing.ValidFrom;
compItem.Publishing.ValidTo = pageItem.Publishing.ValidTo;
compItem.Editing.EndEdit(true, true);
我玩过updateStatistics和silent参数。如果它“静默”,UI会响应,但当然更新仍然需要在后台运行,这可能会导致问题,因为会有一个时间窗口,页面和组件之间的pub限制将会出来同步。
有关更新150件物品的原因有何疑问?有什么方法可以加快速度吗?
这是完整的代码:
public void OnItemSaved(object sender, EventArgs args)
{
Item item = Event.ExtractParameter(args, 0) as Item;
if (item == null)
return;
//if it's a page, then update the page component templates with the same publish restrictions.
if(this.HasBaseTemplate(item, GlobalId.PageBaseTemplate))
{
ItemChanges itemChanges = Event.ExtractParameter(args, 1) as ItemChanges;
if (itemChanges != null &&
(itemChanges.FieldChanges.Contains(__Validfrom) || itemChanges.FieldChanges.Contains(__Validto)))
{
foreach (Item i in this.GetPageComponents(item))
{
try
{
i.Editing.BeginEdit();
i.Publishing.ValidFrom = item.Publishing.ValidFrom;
i.Publishing.ValidTo = item.Publishing.ValidTo;
i.Editing.EndEdit(true, false);
}
catch(Exception ex)
{
i.Editing.CancelEdit();
}
}
}
}
}
protected IEnumerable<Item> GetPageComponents(Item page)
{
var links = page.Links.GetAllLinks(false, true);
var foundIds = new HashSet<ID>();
var foundComponentIds = new HashSet<ID>();
var componentIds = new List<ID> { page.ID };
using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
while (componentIds.Any())
{
var query = context.GetQueryable<LinkSearchResultItem>();
var predicate = PredicateBuilder.False<LinkSearchResultItem>();
foreach (var id in componentIds)
{
predicate = predicate.Or(sri => sri.ItemId == id);
}
query = query.Where(predicate);
var results = query.GetResults().Hits.Select(h => h.Document);
foundIds.Add(componentIds);
componentIds.Clear();
componentIds.AddRange(results
.Where(sri => (sri.Path.StartsWith("/sitecore/content/BECU/Global/Page Components/", StringComparison.InvariantCultureIgnoreCase) || sri.ItemId == page.ID) && sri.Links != null)
.SelectMany(sri => sri.Links)
.Except(foundIds));
foundComponentIds.Add(results
.Where(sri => (sri.Path.StartsWith("/sitecore/content/BECU/Global/Page Components/", StringComparison.InvariantCultureIgnoreCase)))
.Select(sri => sri.ItemId));
}
}
var database = page.Database;
return foundComponentIds.Select(id => database.GetItem(id)).Where(i => i != null);
}
答案 0 :(得分:0)
我建议您尝试使用Sitecore.Data.BulkUpdateContext
包装编辑代码,如下所示
...
using(new Sitecore.Data.BulkUpdateContext())
{
foreach (Item i in this.GetPageComponents(item))
{
try
{
i.Editing.BeginEdit();
i.Publishing.ValidFrom = item.Publishing.ValidFrom;
i.Publishing.ValidTo = item.Publishing.ValidTo;
i.Editing.EndEdit(true, false);
}
catch(Exception ex)
{
i.Editing.CancelEdit();
}
}
}
...
在Sitecore中更新项目时,由于更新项目而导致其他几个后台进程和事件。这样的示例是索引,其将一次减慢大量项目的更新。
BulkUpdateContext将禁用大部分这些事件和进程,直到更新完成,从而有望加快项目的更新。
注意:我自己还没有使用这个BulkUpdateContext,但我发现了几个帖子,包括this Stackoverflow问题,它声称BulkUpdateContext只能提高项目创建速度,而不是更新。但是,这可能仅适用于当时正在使用的特定版本的Sitecore。 Sitecore(7.X和8)的新版本可能不再是这种情况,所以我认为它仍值得一试。