Normally I just create new properties if I've created the wrong type and then delete the old. In rare cases I've used a scheduled job I custom made to migrate data to new type. But normally you can get away with redoing some stuff manually after you found a better way to implement it.
Sometimes I do a completely new page type based on an old and then you can use the conversion job that already exist to migrate your data to the new model.
If you think about your page types like you think about classes and data base tables and keep them focused on what data they should be storing you can normally expand your model without breaking too much. Working with interfaces to indicate what page types support what functionality also helps in the long run.
I have used a dev/debug WebApi controller for similar tasks, e.g. this removes missing properties altogether (I'm bad with names).
[RoutePrefix("api/dev")] [Authorize(Roles = "WebAdmins")] public class DevApiController : ApiController { private readonly ContentTypeModelRepository _contentTypeModelRepository; private readonly IPropertyDefinitionRepository _propertyDefinitionRepository; private readonly PageTypeRepository _pageTypeRepository; private readonly BlockTypeRepository _blockTypeRepository; public DevApiController(ContentTypeModelRepository contentTypeModelRepository, IPropertyDefinitionRepository propertyDefinitionRepository, PageTypeRepository pageTypeRepository, BlockTypeRepository blockTypeRepository) { _contentTypeModelRepository = contentTypeModelRepository; _propertyDefinitionRepository = propertyDefinitionRepository; _pageTypeRepository = pageTypeRepository; _blockTypeRepository = blockTypeRepository; } [HttpGet] [Route("missing-properties")] public IList<MissingPropertyResult> GetMissingProperties() { var pageProperties = from type in _pageTypeRepository.List() from property in type.PropertyDefinitions.Where(property => IsMissingModelProperty(property)) select new MissingPropertyResult { TypeName = type.Name, PropertyName = property.Name, PropertyId = property.ID }; var blockProperties = from type in _blockTypeRepository.List() from property in type.PropertyDefinitions.Where(property => IsMissingModelProperty(property)) select new MissingPropertyResult { TypeName = type.Name, PropertyName = property.Name, PropertyId = property.ID }; return pageProperties.Concat(blockProperties).ToList(); } [HttpGet] // GET because it's easier to call (with a browser) than DELETE [Route("missing-properties/delete")] public IList<MissingPropertyResult> DeleteMissingProperties() { var properties = GetMissingProperties().ToList(); foreach (var property in properties) { var writable = _propertyDefinitionRepository.Load(property.PropertyId).CreateWritableClone(); _propertyDefinitionRepository.Delete(writable); } return properties; } private bool IsMissingModelProperty(PropertyDefinition propertyDefinition) { return propertyDefinition != null && propertyDefinition.ExistsOnModel && _contentTypeModelRepository.GetPropertyModel(propertyDefinition.ContentTypeID, propertyDefinition) == null; } public class MissingPropertyResult { public string TypeName { get; set; } public string PropertyName { get; set; } public int PropertyId { get; set; } } }
You can also use migration steps to handle property name changess from code http://world.episerver.com/documentation/Class-library/?documentId=cms/9/93B6FD87. Changing value types are trickier though. I'm trying to avoid that.
If you specify a guid on every content type, it's easy to rename them, it will just automatically work.
These are some good tips and information for moving forward. Thank you guys for helping.
Regarding the missing properties: when you delete a "missing" property, is the data associated with it also removed or does it linger in the database? I haven't taken a dive into the Episerver database yet so I don't know what the structure or behavior is like.
If the property is no longer defined in code, it will be defined as "missing". Any data associated with the property is still there until you delete the property.
Guids on all content types is a must yes. Renaming will not be fun otherwise :)
I am learning as I go along with a project and that means a decent amount of trial and error, testing, and changing, and "Oops, I didn't want to do that." What's the best way to deal with this when working with Properties on pages, especially when you add data in and realize you actually didn't want that property type, and want to change it? From what I have read and and see so far, changing a property type isn't exactly easy or suggested when data is involved, but what about those situations where you create a property to test, and then realized the type is not what you wanted? Is there a way to remove the data for the property type so you can keep everything else in your code and only change the property type? Or is there a different recommended approach?