Started down a dark path looking at converting existing content types from an inherited to composed structure - I know there's nothing fundamentally 'wrong' with inheritance, but compositions are much more flexible, so it's a dark path I need to tread.
So far, I've done this:
created a set of new, base compositions which cover all the existing inherited properties (ie we inherit metadata fields from a base doc type, so created a corresponding metadata composition). It's not as granular as I'd like, but it's a start.
next, I've iterated through all the existing content types (200+), and grabbed the ones that inherit from the base type
I create a copy of each of those types, adding __new as a suffix on the alias
since copying the content type only copies it's explicitly declared properties, I can then add the appropriate compositions back onto the new copy. All good, working well.
at this point, I now have the existing set of inheritance-based content types, and a new set of composition-based content types, in a 1:1 relationship, so I should be able to take node x of type foo, and convert it to type foo__new, right?
no. Not right, not yet.
I could run though every node via the content service, change the type, republish, wait, and go again. That's going to take a while with 20k nodes in the site. Too slow.
Instead, I've tried this:
get all the content types
map them into a dictionary relating new type and old type
created a temporary db table
populated that table with the id relationships from the dictionary
now I have a table from which I can look up an existing (inheritance-based) content type, and find the composition-based type it relates to. Cool, just like the dictionary data.
from there, I can do this: update cmsContent set contentType = Temp.NewTypeId from Temp where Temp.OldTypeId = cmsContent.contentType to update the cmsContent table, replacing the old type id with the new one.
This doesn't update the cmsContentXml table, but contentService.RebuildXmlStructures() will, eventually.
And this is where it all falls over. The backoffice still loads the tree nicely, the nodes are all of the new content type, but they don't have any data.
So there's an additional step that I'm missing and would love someone to point me towards it...
NINJA-EDIT: Using the backoffice UI to switch types works fine, so the issue is the db stuff, not the content types themselves.
Hey Dave, I've had a dig into how it's managed when calling changeContentType on an IContent item, but didn't get far - there's a simple update to the content type ID, but there must be more going on to update XML etc.
Was hoping to find an SQL way of doing it, really just for the performance benefits.
Hey Nathan, did you ended up fixing this? I have some doctypes that inherit from a base. I'm trying to migrate the content from v7 to v10, and it turns out that some of the 'children' of that base need to be Elements but other still need to be IPublishedContent, so I need to remove the inheritance.
Hey Mario, I did indeed. Ended up going for a SQL-only solution, which worked allowed me to convert everything without any issues. I'll try find the SQL (was from my previous job, but might have a copy floating around somewhere).
I'll get back to you :)
EDIT => try this as a starting point. Actual solution will likely differ based on how your doctypes are set up, but should be a good start.
Converting from inheritance to composition
Hi all
Started down a dark path looking at converting existing content types from an inherited to composed structure - I know there's nothing fundamentally 'wrong' with inheritance, but compositions are much more flexible, so it's a dark path I need to tread.
So far, I've done this:
I could run though every node via the content service, change the type, republish, wait, and go again. That's going to take a while with 20k nodes in the site. Too slow.
Instead, I've tried this:
update cmsContent set contentType = Temp.NewTypeId from Temp where Temp.OldTypeId = cmsContent.contentType
to update the cmsContent table, replacing the old type id with the new one.This doesn't update the cmsContentXml table, but
contentService.RebuildXmlStructures()
will, eventually.And this is where it all falls over. The backoffice still loads the tree nicely, the nodes are all of the new content type, but they don't have any data.
So there's an additional step that I'm missing and would love someone to point me towards it...
NINJA-EDIT: Using the backoffice UI to switch types works fine, so the issue is the db stuff, not the content types themselves.
Hi Nathan,
Maybe you can have a look on how Umbraco handles changing doctypes on existing nodes. There is a change doctype context menu action.
Dave
Hey Dave, I've had a dig into how it's managed when calling changeContentType on an IContent item, but didn't get far - there's a simple update to the content type ID, but there must be more going on to update XML etc.
Was hoping to find an SQL way of doing it, really just for the performance benefits.
If you look at the code you probably can work out the database queries.
Probably Chauffeur would be a good option to do this, so you can run it outside of a web context.
But I have a suspiscion you are already doing that
Dave
Ultimately, yes, outside web context - it's 27k publish operations, so if I can avoid 27k calls to contentservice I'll be happy...
Hey Nathan, did you ended up fixing this? I have some doctypes that inherit from a base. I'm trying to migrate the content from v7 to v10, and it turns out that some of the 'children' of that base need to be Elements but other still need to be IPublishedContent, so I need to remove the inheritance.
Hey Mario, I did indeed. Ended up going for a SQL-only solution, which worked allowed me to convert everything without any issues. I'll try find the SQL (was from my previous job, but might have a copy floating around somewhere).
I'll get back to you :)
EDIT => try this as a starting point. Actual solution will likely differ based on how your doctypes are set up, but should be a good start.
https://gist.github.com/nathanwoulfe/aaa07b01d3e042d9559a2f1a15961602
is working on a reply...