EpiServer技术问询:如何查询Block是否被已发布页面使用?
嘿,这个问题我维护EpiServer项目时也碰到过——随着迭代堆积的无用Block确实头疼,分享几个实用方法帮你判断:
方法一:用CMS后台内置的引用查询(最快捷的可视化方式)
登录EpiServer CMS后台,找到要检查的Block并进入编辑页面,在右侧面板找「References」或「Used by」(不同版本位置略有差异,一般在内容属性区下方)。这里会列出所有引用该Block的内容项,包括页面、其他Block等,还能筛选只看已发布的内容,一眼就能确认是否被在用的页面引用。
- 小提示:哪怕Block是嵌套在其他Block里被间接引用的,这个功能也能追踪到,不用额外排查层级。
方法二:编写代码批量查询(适合自动化或批量检查场景)
如果要批量检查多个Block,或者需要集成到自定义工具里,用代码查询更高效。利用EpiServer的ContentRepository和ReferenceConverter就能实现:
using EPiServer.Core; using EPiServer.ServiceLocation; using System.Collections.Generic; using System.Linq; public class BlockUsageChecker { private readonly IContentRepository _contentRepository; private readonly IReferenceConverter _referenceConverter; public BlockUsageChecker() { _contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>(); _referenceConverter = ServiceLocator.Current.GetInstance<IReferenceConverter>(); } // 单个Block:检查是否被已发布页面引用 public bool IsBlockUsedByPublishedPages(ContentReference blockReference) { var allReferences = _contentRepository.GetReferencesToContent(blockReference, false); foreach (var reference in allReferences) { var contentLink = _referenceConverter.GetContentReference(reference); if (contentLink == null) continue; if (_contentRepository.TryGet<PageData>(contentLink, out var page)) { // 只判断已发布状态的页面 if (page.Status == VersionStatus.Published) { return true; } } } return false; } // 批量查询:获取某类未被已发布页面使用的Block public IEnumerable<BlockData> GetUnusedBlocks<TBlock>() where TBlock : BlockData { var allBlocks = _contentRepository.GetDescendents(ContentReference.RootPage) .Select(link => _contentRepository.Get<IContent>(link)) .OfType<TBlock>(); foreach (var block in allBlocks) { if (!IsBlockUsedByPublishedPages(block.ContentLink)) { yield return block; } } } }
- 扩展说明:如果需要排除特定页面类型,或者只检查某段路径下的页面,在
TryGet的判断里加额外条件即可。
方法三:直接查询数据库(适合紧急排查或熟悉DB结构的场景)
EpiServer的内容引用存在tblContentSoftLink表中,直接写SQL就能快速定位:
-- 替换123为目标Block的ContentID SELECT DISTINCT c.ContentID, c.Name, c.URLSegment FROM tblContentSoftLink sl JOIN tblContent c ON sl.OwnerContentID = c.ContentID WHERE sl.ReferencedContentID = 123 AND c.Status = 4 -- 4对应已发布状态(不同版本可能有差异,提前确认) AND c.ContentTypeID IN (SELECT ContentTypeID FROM tblContentType WHERE Name LIKE '%Page%')
- 注意:不同EpiServer版本的DB表结构可能微调,执行前最好确认状态值和表名对应关系。
几个额外提醒
- 间接引用不用怕:不管Block是直接被页面引用,还是嵌套在其他Block里被间接引用,上面的方法都能检测到;
- 区分版本状态:一定要只筛选已发布页面,别误删了还在草稿中被使用的Block;
- 清理前备份:确认无用后,删除前最好先备份内容,避免误操作。
内容的提问来源于stack exchange,提问作者Ayo Adesina
相关产品推荐
相关产品推荐

