首页 > 解决方案 > 将 PropertyData 迁移到新的 PropertyType

问题描述

我们有一个使用属性编辑器的现有PropertyType调用。IsPublicUmbraco.TrueFalse

需求已经改变,这个值现在需要由多个复选框来表示,这些复选框由具有 Values PublicGroup1、的 Enum 驱动Group2

这一切都按预期工作,但是对于成千上万的文档,我们希望避免我们的内容编辑器手动填充它们。

在 Umbraco 中保存一个文档,我可以看到它在表中创建了一个条目,其中包含列中cmsPropertyData的值。[ "Public", "Group1", "Group2" ]dataNvarchar

IsPublic我已经编写了一个脚本来根据原始标志的值在该表中插入一行。

但是,在运行此程序后,在 Umbraco 中打开文档时,不会显示更改。

用于更新的脚本是

DECLARE @HasPublicFlag NVARCHAR(50) = '[    "Public",    "Group1",    "Group2"  ]'
DECLARE @NoPublicFlag NVARCHAR(50) = '[    "Group1",    "Group2"  ]'

DECLARE @feature INT = (SELECT nodeId FROM cmsContentType WHERE Alias = 'Feature')

--Existing IsPublic flag
DECLARE @featureIsPublic INT = (SELECT id FROM cmsPropertyType WHERE Alias = 'IsPublic' AND contentTypeId = @feature)

--New PropertyType
DECLARE @featureRoleRestriction INT = (SELECT id FROM cmsPropertyType WHERE Alias = 'documentRoleRestriction' AND contentTypeId = @page)

--Get feature document versions that are either newest version or published
;WITH FeatureDocumentsToUpdate AS
(
    SELECT d.*, pd.dataInt
    FROM cmsDocument d 
    JOIN cmsPropertyData pd ON pd.versionId = d.versionId
    LEFT JOIN cmsPropertyData pd2 ON pd2.versionId = d.versionId AND pd2.propertytypeid = @featureRoleRestriction
    WHERE (d.newest = 1 OR d.Published = 1) AND pd.propertytypeid = @featureIsPublic AND pd2.id IS NULL
)

--INSERT INTO cmsPropertyData based on value of existing flag
INSERT INTO cmsPropertyData(contentNodeId, versionId, propertytypeid, dataNvarchar)
SELECT s.nodeId, versionId, @featureRoleRestriction, 
    CASE WHEN s.dataInt = 0 THEN @NoPublicFlag ELSE @HasPublicFlag END AS NewValue
FROM FeatureDocumentsToUpdate s

是否有另一个表需要更新,或者有更好的方法来做到这一点?

标签: umbracoumbraco7

解决方案


我的猜测是您需要重新发布所有受影响的页面以供缓存等正确更新和填充新值。

对于 10,000 多个文档,完全重新发布所有内容可能会很慢。

您还可以尝试更新 cmsContentXml 表中每个页面的 XML 以获得正确的值,然后重建站点的检查索引,这应该可以解决问题并且速度更快一些。这是因为该表的内容用于重建索引以节省速度。

另一种选择是编写一个 API 控制器任务,您可以运行一次然后删除以使用 Umbraco 服务更新所有值,但同样,我认为这会很慢,我认为您正在谈论的页面数量.


推荐阅读