Monday, May 7, 2012

CRM 2011: Deleting Attributes, Entities, Relationships or OptionSets from Managed Solutions

Once you install a managed solution you are not allowed to delete any of its entities, attributes, relationships, reports and OptionSets. This post provides a simple and supported workaround if you absolutely need to delete one of these components from a deployed managed solution.

Working with managed solutions in production environments bring multiple advantages (see previous post on managed vs. unmanaged solutions), however, one of the disadvantages is that once you deploy a managed solution, you are no longer able to delete some of its components. A typical example is that you deploy a solution with a custom entity and you figure out that you must change the data type of an attribute. CRM in general will not allow you to change the data type of an attribute, you will need to delete the attribute and re-create it with the new type (even if you use unmanaged solutions); however if your managed solution is already deployed you cannot delete the attribute, so what do you do? I will offer 3 different alternatives I have used in the past:


1. Hide instead of delete. The easiest solution is to simply create the new attribute with the correct data type and completely hide the old attribute from all views, forms, reports, etc. In many cases, deleting an attribute in production is unacceptable because of data loss so this alternative is the safest and most conservative as you get to keep the old data. The disadvantage is that you will have useless columns in your database and the old attribute will continue to appear in Advanced Find.


2. Use a holding solution to delete any component from your deployed managed solution. This is my favourite approach as it has the advantage of completely deleting from the system the unwanted components without losing any data. This is how it works: Assume you have a solution XXX which contains a custom entity and one of the attributes is of type “Single Line of Text” but you want to change it to “Multiple Lines of Text”. In your target environment you should have solution XXX as managed and in your development environment you should have solution XXX as unmanaged.
  1. In your development environment create a new solution “XXX_holding”. The publisher must be the same as the publisher of your XXX solution.
  2. Add all the components of the XXX solution to your XXX_holding solution*.
  3. Export XXX_holding as managed.
  4. Import XXX_holding to your target environment.
  5. Delete XXX solution from your target environment. No data is lost because all the customizations remain in the holding solution.
  6. In your development environment delete the attribute (you will need to adjust views, forms, etc.).
  7. Export XXX as managed.
  8. Import XXX to your target environment
  9. Delete XXX_holding from your target environment. The attribute will now be deleted from all environments. There is no data loss except for the data that was saved in the old attribute which was deleted.
  10. Now that the attribute is deleted, if you want the attribute back but with a different data type you just need to re-create it in dev and promote the solution to your target environment.
* Note: You can avoid steps 1-3 if you simply open your XXX solution zip file and in the solution.xml file you update the solution unique name to “XXX_holding”. This way you guarantee that you have all the components of XXX also in XXX_holding.


3. Uninstall and re-install solution. If you absolutely need to wipe out the old attribute from the system, you could also uninstall the entire managed solution, make the appropriate changes in your development environment and then re-deploy a clean and correct version of your managed solution. The big disadvantage here is that you will lose your data if it relies on the customizations of your solution, which is usually unacceptable unless you have no data to retain or the data is not important.


4. Use unmanaged solutions instead of managed solutions. While it is true that with unmanaged solutions it is simpler to manually delete any component, it is also true that deploying unmanaged solutions to a production environment has multiple disadvantages and is not a good practice in my perspective. It might also be too late for you to switch to unmanaged solutions. You can read more on best practices around managed vs. unmanaged solutions here. There’s also an interesting white paper from Microsoft for building ISV solutions.


Some posts in the MSDN forums additionally suggest that Microsoft is aware of this limitation and might consider a better solution in the future. For the time being I have found the holding solution approach to work well, please let me know if you have other experiences or suggestions!

18 comments:

  1. I came to same second option for deleting web resources, fields.
    But before step 3, I delete field of entity in development environment and only then export solution XXX_holding.
    Otherwise, you will not be able to import solution XXX in step 8, as you cannot change type of existing field when importing solution.

    ReplyDelete
  2. "...deploying MANAGED solutions to a production environment has multiple disadvantages and is not a good practice in my perspective."

    Just making sure I understand, did you mean "...deploying UNMANAGED solutions to a production environment has multiple disadvantages and is not a good practice in my perspective"?

    ReplyDelete
  3. Juan, you're absolutely right, it was a typo. I have corrected it, thanks for reporting it!

    ReplyDelete
  4. Gonzalo, do you have a time/risk estimate for option # 2 for an environment with medium-high amount of customizations?

    ReplyDelete
  5. I would say the risk is low (provided you have a roll-back mechanism in place) and it should not take you longer than 1 day + testing. You can try first in a dev environment to verify.

    ReplyDelete
  6. I did option 2 on CRM Online. However, now when I update the primary solution it fails with the error: 0x80040217, solution With Id = XXX-GUID-XXX Does Not Exist.

    It fails on an entiy which had a relationship with the deleted entity so I wonder if there is still something in there. I have looked but can't see anything out of place.

    Ever seen this happen and have an idea of what to check?

    ReplyDelete
  7. This does not work anymore since rollup 6.
    Some data will be still in the database when removing the managed solution (like attributemap values and also form labels) These cause major errors when your system now is running rollup 11. Microsoft then advises to re-install and import all data again.

    ReplyDelete
  8. Gonz, do you have any response or verification on the Anyonymous comment from January 18, 2013 about rollup 6?

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. Is the holding solution approach unsupported by MS?

    ReplyDelete
    Replies
    1. Grey area. Definitely not recommended in production environment. However, you should be able to delete managed components in future version of CRM

      Delete
    2. Yes, it is. Microsoft uses the holding solution approach when you deploy your solutions via the Package Deployer.

      Delete
    3. Actually Microsoft acknowledges it but does not specifically endorse it. In CRM 2016 they added the necessary SDK messages and UI to support this scenario and is now supported hen you use the solution upgrade "staging" process.

      Delete
  11. Hi, I have an issue in that a relationship isn't in my unmanaged dev environment but when I import it as a managed solution into UAT it's there. And as it's managed I can't delete it. Where is this relationship coming from and any idea how do I delete?! Thanks

    ReplyDelete
  12. Hi Gonz,
    Is there a way to change the attribute state from managed to unmanaged from unmanaged solution

    ReplyDelete