Content Migration from one to another property for live site
In one of my projects I recently faced an issue where we have to change all the standard category properties to IList<ContentReference> and the site was live so we just couldn't take the field and get it over with.
So I create new IList<ContentReference> properties and migrate the data and change the logic. Here are the steps that I followed.
Step To follow:-
-
- Create new fields -- for all categories while don't remove old ones once
- Create a scheduled job that migrates data from the old field to the new field
- Switch the logic from old to new fields as new fields have multiple categories
- remove old fields (only after running the migration job)
Step-1:-
We create new Ilist<contentreference> properties for every standard category property.
[Display(
Name = "Something",
GroupName = SystemTabNames.Content,
Order = 10)]
[Categories]
public virtual IList<ContentReference> Something { get; set; }
Step-2:-
Here we have to write the code so that content that is already existing on the live site migrates from old to new properties.
Few things that I did while creating a scheduled job:
-
-
-
- Get all the pages where I changed the property, So for that, I created a generic method.
-
-
private IEnumerable<T> GetDataList<T>()
where T : ContentData
{
var objectType = _contentTypeRepository.Load<T>();
var usages = _contentModelUsage.ListContentOfContentType(objectType)
.Select(x => x.ContentLink.ToReferenceWithoutVersion())
.Distinct()
.Select(x => _contentLoader.Get<IContentData>(x))
.OfType<T>()
.ToList();
return (IEnumerable<T>)usages;
}
-
-
-
- After this method call loop through all the pages and create a writeable clone so that we change the data
- invoke the list and then assign the value to it.
-
-
OnStatusChanged($"Migration start for ChapterDetailPage");
var chapterDetailPages = GetDataList<ChapterDetailPage>();
if (chapterDetailPages != null)
{
foreach (var cdp in chapterDetailPages)
{
//migrate data
var page = (ChapterDetailPage)cdp.CreateWritableClone();
page.LocationIdNew = new List<ContentReference>();
var hit = _getaCatRep.TryGet(new ContentReference(page.LocationID), out stdCat) ? stdCat : null;
if (hit != null)
{
page.LocationIdNew.Add(hit.ContentLink);
_contentRepository.Save(page, SaveAction.Publish, AccessLevel.NoAccess);
}
}
}
OnStatusChanged($"Migration end for ChapterDetailPage");
-
-
-
- Then Save the page using the Content Repository.
-
-
Step-3
Change all the existing logic so that pages don't error.
Step-4
The last step will be to remove all old properties.
Comments