Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Nathan Woulfe 447 posts 1664 karma points MVP 5x hq c-trib
    Apr 15, 2019 @ 05:57
    Nathan Woulfe
    1

    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:

    • 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.

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Apr 15, 2019 @ 06:20
    Dave Woestenborghs
    0

    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

  • Nathan Woulfe 447 posts 1664 karma points MVP 5x hq c-trib
    Apr 15, 2019 @ 07:40
    Nathan Woulfe
    0

    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.

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Apr 15, 2019 @ 07:57
    Dave Woestenborghs
    0

    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

  • Nathan Woulfe 447 posts 1664 karma points MVP 5x hq c-trib
    Apr 16, 2019 @ 00:18
    Nathan Woulfe
    0

    Ultimately, yes, outside web context - it's 27k publish operations, so if I can avoid 27k calls to contentservice I'll be happy...

  • Mario Lopez 168 posts 952 karma points MVP 3x c-trib
    Oct 18, 2022 @ 03:05
    Mario Lopez
    0

    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.

  • Nathan Woulfe 447 posts 1664 karma points MVP 5x hq c-trib
    Oct 19, 2022 @ 06:37
    Nathan Woulfe
    0

    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

Please Sign in or register to post replies

Write your reply to:

Draft