diff --git a/src/Umbraco.Core/Models/ValueStorageType.cs b/src/Umbraco.Core/Models/ValueStorageType.cs
index 975369f993..e7e4f8b354 100644
--- a/src/Umbraco.Core/Models/ValueStorageType.cs
+++ b/src/Umbraco.Core/Models/ValueStorageType.cs
@@ -14,13 +14,13 @@ public enum ValueStorageType
// changing the casing of values.
///
- /// Store property value as NText.
+ /// Store property value as NVarchar(max).
///
[EnumMember]
Ntext,
///
- /// Store property value as NVarChar.
+ /// Store property value as NVarChar(512).
///
[EnumMember]
Nvarchar,
diff --git a/src/Umbraco.Core/PropertyEditors/ValueTypes.cs b/src/Umbraco.Core/PropertyEditors/ValueTypes.cs
index ac6e6a9bb8..dc1e636c7f 100644
--- a/src/Umbraco.Core/PropertyEditors/ValueTypes.cs
+++ b/src/Umbraco.Core/PropertyEditors/ValueTypes.cs
@@ -45,7 +45,7 @@ public static class ValueTypes
public const string Json = "JSON"; // NText
///
- /// Text value (maps to text database type).
+ /// Text value (maps to nvarchar(max) database type).
///
public const string Text = "TEXT"; // NText
@@ -55,7 +55,7 @@ public static class ValueTypes
public const string Time = "TIME"; // Date
///
- /// Text value (maps to varchar database type).
+ /// Text value (maps to nvarchar(512) database type).
///
public const string String = "STRING"; // NVarchar
diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
index e99ce46587..7fed5a6afb 100644
--- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
+++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
@@ -2060,7 +2060,7 @@ internal sealed class DatabaseDataCreator
NodeId = -43,
EditorAlias = Constants.PropertyEditors.Aliases.CheckBoxList,
EditorUiAlias = "Umb.PropertyEditorUi.CheckBoxList",
- DbType = "Nvarchar",
+ DbType = "Ntext",
});
}
diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
index b02c56fea6..a62ce1d8a1 100644
--- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
+++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
@@ -126,5 +126,6 @@ public class UmbracoPlan : MigrationPlan
// To 17.0.0
To("{17D5F6CA-CEB8-462A-AF86-4B9C3BF91CF1}");
+ To("{EB1E50B7-CD5E-4B6B-B307-36237DD2C506}");
}
}
diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_17_0_0/MigrateCheckboxListDataTypesAndPropertyData.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_17_0_0/MigrateCheckboxListDataTypesAndPropertyData.cs
new file mode 100644
index 0000000000..35873b9501
--- /dev/null
+++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_17_0_0/MigrateCheckboxListDataTypesAndPropertyData.cs
@@ -0,0 +1,50 @@
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_17_0_0;
+
+///
+/// Migrates data types based on the Umbraco.CheckBoxList property editor to store data in the text column without length restriction.
+/// Also migrates the data for properties this property editor from the length restricted field (varcharValue - nvarchar(512)), to the
+/// one without a restriction (textValue - nvarchar(max)).
+///
+public class MigrateCheckboxListDataTypesAndPropertyData : AsyncMigrationBase
+{
+ private readonly IDataTypeService _dataTypeService;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MigrateCheckboxListDataTypesAndPropertyData(IMigrationContext context, IDataTypeService dataTypeService)
+ : base(context) => _dataTypeService = dataTypeService;
+
+ ///
+ protected override async Task MigrateAsync()
+ {
+ // Update the definition of the datatypes.
+ IEnumerable dataTypes = await _dataTypeService.GetByEditorAliasAsync(Constants.PropertyEditors.Aliases.CheckBoxList);
+ foreach (IDataType dataType in dataTypes)
+ {
+ dataType.DatabaseType = ValueStorageType.Ntext;
+ await _dataTypeService.UpdateAsync(dataType, Constants.Security.SuperUserKey);
+ }
+
+ // Copy from varcharValue to textValue and set varcharValue to null for all property data stored using data types based on
+ // the Umbraco.CheckBoxList property editor.
+ string sql = $@"
+UPDATE umbracoPropertyData
+SET textValue = varcharValue, varcharValue = NULL
+WHERE propertyTypeId IN (
+ SELECT id
+ FROM cmsPropertyType
+ WHERE dataTypeId IN (
+ SELECT nodeId
+ FROM umbracoDataType
+ WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.CheckBoxList}'
+ )
+)
+AND varcharValue IS NOT NULL";
+ await Database.ExecuteAsync(sql);
+ }
+}
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs
index cd06118041..9f9606e3f0 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs
@@ -12,6 +12,7 @@ namespace Umbraco.Cms.Core.PropertyEditors;
///
[DataEditor(
Constants.PropertyEditors.Aliases.CheckBoxList,
+ ValueType = ValueTypes.Text, // We use the Text value type to ensure we don't run out of storage space in the database field with large lists with multiple values selected.
ValueEditorIsReusable = true)]
public class CheckBoxListPropertyEditor : DataEditor
{