diff --git a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs index fde47f410e..eb9a66a7f2 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs @@ -18,6 +18,7 @@ namespace Umbraco.Core.Models.Rdbms public int NodeId { get; set; } [Column("contentType")] + [ForeignKey(typeof(ContentTypeDto), Column = "nodeId")] public int ContentTypeId { get; set; } [ResultColumn] diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs index 33595e3905..ca0cf7ebd2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs @@ -90,7 +90,14 @@ namespace Umbraco.Core.Persistence.Migrations.Initial return new Version(6, 2, 0); } } - + + //if the error indicates a problem with the constraint FK_cmsContent_cmsContentType_nodeId then it is not version 7.2 + // since this gets added in 7.2.0 so it must be the previous version + if (Errors.Any(x => x.Item1.Equals("Constraint") && (x.Item2.InvariantEquals("FK_cmsContent_cmsContentType_nodeId")))) + { + return new Version(7, 0, 0); + } + return UmbracoVersion.Current; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs new file mode 100644 index 0000000000..2936a25ba2 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs @@ -0,0 +1,50 @@ +using System.Data; +using Umbraco.Core.Configuration; +using Umbraco.Core.Models.Rdbms; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero +{ + [Migration("7.2.0", 1, GlobalSettings.UmbracoMigrationName)] + public class AddMissingForeignKeyForContentType : MigrationBase + { + public override void Up() + { + //SELECT * FROM cmsContent WHERE NOT EXISTS (SELECT cmsContentType.nodeId FROM cmsContentType WHERE cmsContentType.nodeId = cmsContent.contentType) + + //Before we can add the foreign key there cannot be any orphaned content, media, members + var orphanedIds = Context.Database.Fetch("SELECT contentType FROM cmsContent WHERE NOT EXISTS (SELECT cmsContentType.nodeId FROM cmsContentType WHERE cmsContentType.nodeId = cmsContent.contentType)"); + foreach (var orphanedId in orphanedIds) + { + Delete.FromTable("cmsTask").Row(new { nodeId = orphanedId }); + Delete.FromTable("umbracoUser2NodeNotify").Row(new { nodeId = orphanedId }); + Delete.FromTable("umbracoUser2NodePermission").Row(new { nodeId = orphanedId }); + Delete.FromTable("umbracoRelation").Row(new { parentId = orphanedId }); + Delete.FromTable("umbracoRelation").Row(new { childId = orphanedId }); + Delete.FromTable("cmsTagRelationship").Row(new { nodeId = orphanedId }); + Delete.FromTable("umbracoDomains").Row(new { domainRootStructureID = orphanedId }); + Delete.FromTable("cmsDocument").Row(new { nodeId = orphanedId }); + Delete.FromTable("cmsPropertyData").Row(new { contentNodeId = orphanedId }); + Delete.FromTable("cmsMember2MemberGroup").Row(new { Member = orphanedId }); + Delete.FromTable("cmsMember").Row(new { nodeId = orphanedId }); + Delete.FromTable("cmsPreviewXml").Row(new { nodeId = orphanedId }); + Delete.FromTable("cmsContentVersion").Row(new { ContentId = orphanedId }); + Delete.FromTable("cmsContentXml").Row(new { nodeId = orphanedId }); + Delete.FromTable("cmsContent").Row(new { nodeId = orphanedId }); + Delete.FromTable("umbracoNode").Row(new { id = orphanedId }); + } + + Create.ForeignKey("FK_cmsContent_cmsContentType_nodeId") + .FromTable("cmsContent") + .ForeignColumn("contentType") + .ToTable("cmsContentType") + .PrimaryColumn("nodeId") + .OnDelete(Rule.None) + .OnUpdate(Rule.None); + } + + public override void Down() + { + throw new DataLossException("Cannot downgrade from a version 7.2 database to a prior version, the database schema has already been modified"); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs index 1cff1cad88..281c679a84 100644 --- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs @@ -381,14 +381,17 @@ ON cmsPropertyType.dataTypeId = cmsDataTypePreValues.datatypeNodeId", docSql.Arg // below if any property requires tag support var allPreValues = new Lazy>(() => { - var preValsSql = new Sql(@"SELECT DISTINCT -cmsDataTypePreValues.id as preValId, cmsDataTypePreValues.value, cmsDataTypePreValues.sortorder, cmsDataTypePreValues.alias, cmsDataTypePreValues.datatypeNodeId -FROM cmsDataTypePreValues -INNER JOIN cmsPropertyType -ON cmsDataTypePreValues.datatypeNodeId = cmsPropertyType.dataTypeId -INNER JOIN - (" + string.Format(parsedOriginalSql, "cmsContent.contentType") + @") as docData -ON cmsPropertyType.contentTypeId = docData.contentType", docSql.Arguments); + var preValsSql = new Sql(@"SELECT a.id as preValId, a.value, a.sortorder, a.alias, a.datatypeNodeId +FROM cmsDataTypePreValues a +WHERE EXISTS( + SELECT DISTINCT b.id as preValIdInner + FROM cmsDataTypePreValues b + INNER JOIN cmsPropertyType + ON b.datatypeNodeId = cmsPropertyType.dataTypeId + INNER JOIN + (" + string.Format(parsedOriginalSql, "DISTINCT cmsContent.contentType") + @") as docData + ON cmsPropertyType.contentTypeId = docData.contentType + WHERE a.id = b.id)", docSql.Arguments); return Database.Fetch(preValsSql); }); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 72ec037aa7..e72d125405 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -389,6 +389,7 @@ +