Tuesday, 18 October 2016

Want to delete a managed component? Use the clone solution feature in CRM 2016.

Have you ever had the need to delete a component present in a managed solution? Let’s say, I have a solution ‘Delete From Managed’ with two entities ‘Entity to Retain’ and ‘Entity To Delete’ at the development server. I export it as a managed solution and then import it at the production server. Everything works fine. Some stage later, you find that ‘Entity To Delete’ is no longer needed and you want to remove it from the production server, but you cannot do so because the solution is a managed one. What do I do now?

Before CRM 2016, there was a work around to this issue i.e. holding solution. In CRM 2016 I’ve found that we could use the clone solution feature to complete this task.

Let’s see it step by step.

The screen below shows my original solution.

First, I clone the solution at the development server.

Notice that cloning solution increases the version number of the solution.

I then, delete the unused entity ‘Entity To Delete’ from the solution. I export it again as a managed solution and then import it at the production server.

The initial screen while importing, where I select the zip file, is shown below,

I click next and get the following screen,

I click next again, and get the following screen,

This is an important step. Here we need to make sure that we select the check box named ‘Stage for Upgrade’.

I click ‘Import’ and the import starts.

Once the import finishes successfully, your CRM instance will have two solutions,

  • DeleteFromManaged
  • DeleteFromManaged_Upgrade (CRM creates this renamed solution)

And you are presented the following screen,

Click ‘Apply Solution Upgrade’.

CRM 2016 will create a solution named same as your solution, but with a suffix ‘_Upgrade’. CRM 2016 will automatically manage to delete the component for you, and at successful completion of this step, you will only have one final solution named ‘DeleteFromManaged’. The entity ‘Entity To Delete’ will no longer be present at the production server.

Hope this helps!!!

Tuesday, 6 September 2016

Points to be kept in mind while working with FetchXML

Few days back, I was asked to write FetchXML that would give a list of incidents, which were shared with a team.

The result should contain incident details along with the names of the teams with which the incident was shared.

The result was ought to have 4 fields,

  • title
  • createdon
  • incident
  • team

I wrote the below mentioned FetchXML for this requirement.

<fetch version="1.0output-format="xml-platformmapping="logicaldistinct="false>
<entity name="incident>
<attribute name="title/>
<attribute name="createdonalias="createdon/>
<attribute name="incidentid/>
<link-entity name="principalobjectaccessto="incidentidfrom="objectidlink-type="inneralias="share>
<filter type="and>
<condition attribute="accessrightsmaskoperator="nevalue="0/>
<condition attribute="principalidoperator="not-null/>
<link-entity name="teamfrom="teamidto="principalobjectaccessidlink-type="outeralias="team>
<attribute name="namealias="teamname/>

The equivalent T-SQL for this will be,

i.createdon as createdon,
t.team as teamname
FROM incident i
INNER JOIN principalobjectacess p ON i.incidentid = p.objectid AND accessrightsmask <> 0
INNER JOIN team t ON t.teamid = p.principalobjectaccessid.

Please take a look at following link for “principalobjectaccess, if you are not familiar with it.

The problem

With this fetchxml, somehow, the result did not include the field of ‘team’ entity. But why?

I took help of XRMToolBox (http://www.xrmtoolbox.com/) to find the reason for the issue and tried executing the FetchXML on a CRM instance whose database was accessible to me.

I executed SQL queries to review the data and found that there was no team related to any of the incidents.
Hence, I shared an incident with a team and analyzed the data in the principalobjectaccess table.
With this change I was able to see the expected data in the SQL query.

And while observing the data, I found that the field ‘principalobjectaccessid’ that I used in to field was incorrect and I needed to use the field ‘principalid’ for join purposes.

Thus, based on the working with SQL query, I modified my fetchxml with the correct field value.
Along with this, I also removed the alias “teamname”.

I made these changes and tested it again. This time it gave me the correct results. The following is the modified FetchXML.

<fetch version="1.0output-format="xml-platformmapping="logicaldistinct="false>
<entity name="incident>
<attribute name="title/>
<attribute name="createdonalias="createdon/>
<attribute name="incidentid/>
<link-entity name="principalobjectaccessto="incidentidfrom="objectidlink-type="inneralias="share>
<filter type="and>
<condition attribute="accessrightsmaskoperator="nevalue="0/>
<condition attribute="principalidoperator="not-null/>
<link-entity name="teamfrom="teamidto="principalidlink-type="outeralias="team>
<attribute name="name/>

Results were,

<createdon date="09/01/2016time="4:00 PM>

Points to be kept in mind while working with FetchXML,

  • The fields mentioned in FetchXML linked entity will only show up in the results if a linked entity record is actually present, otherwise the FetchXMl will simply ignore the fields.
  • If we want an attribute of linked entity in the results, we should not give alias to it. Like, in aforesaid fetchxml, we want team name in the output, so I have not given an alias to it.
  • Whenever we link one entity to another in Fetchxml, we should always keep in mind that the from field comes from the linked entity and to field comes from the main entity. Like, in aforesaid fetchxml, the from field has to be from the team entity.
            <link-entity name="teamfrom="teamidto="principalidlink-type="outer>

Hope this helps!

A simple and quick way to insert data into Many-to-Many relationship in Dynamics CRM is the Drag and drop listbox. http://www.inkeysolutions.com/DynamicCRMDragAndDropListBox.html