Fixed – EntityState must be set to null, Created (for Create message) or Changed (for Update message) exception in Dataverse / Dynamics 365


We might get this error while trying to update one of the records.

Exception Message: EntityState must be set to null, Created (for Create message) or Changed (for Update message).

EntityState of primaryEntity: Unchanged, RequestName: Update

ErrorCode: -2147220989

A computer screen shot of a computer

Description automatically generated

The error occurs when OrganizationServiceContext tries to update an entity that has not been marked as modified. The EntityState remains Unchanged, and Dataverse expects it to be Changed or null for update operations.

OrganizationServiceContext automatically tracks entities’ states. When we retrieve an entity, it is set to Unchanged by default.

If we modify the entity without informing the context (e.g., using UpdateObject()), the context still thinks the entity is Unchanged, leading to this error during the update process.

A screenshot of a computer

Description automatically generated

This error typically happens within OrganizationServiceContext since it relies on internal state-tracking mechanisms, with IOrganizationService (e.g., Retrieve or RetrieveMultiple), we typically don’t run into this error because entities retrieved via IOrganizationService aren’t tracked in the same way.

There are 2 ways to resolve this error.

  1. Use UpdateObject, it explicitly tells the context that the entity has been changed followed by SaveChanges() to commit the changes.
A computer screen shot of a program

Description automatically generated

2. Create a new Entity object for update.

Sample Code –

 if (myServiceClient.IsReady)
        {
            using (var context = new OrganizationServiceContext(myServiceClient))
            {
                // Retrieve leads where the 'lastname' contains 'Test'
                var leadColl = from lead in context.CreateQuery("lead")
                               where lead.GetAttributeValue<string>("lastname").Contains("Test")
                               select lead;

                // use Update Object
                foreach (var lead in leadColl)
                {
                    lead.Attributes["subject"] = "Updated Subject" + DateTime.Now.ToLongTimeString();
                    context.UpdateObject(lead);
                    context.SaveChanges();
                }

                // or create a new Entity object
                foreach (var lead in leadColl)
                {
                    Entity leadToUpdate = new Entity("lead", lead.Id)
                    {
                        ["subject"] = "Updated Subject" + DateTime.Now.ToLongTimeString()
                    };
                    myServiceClient.Update(leadToUpdate);
                }     
            }
        }

Hope it helps..

Advertisements

Add line break / new line for description field of Email – Dataverse / Power Automate


In one of our requirements, we wanted to create/send an email on the creation/update of the case with the description of the email same as the description of the case.

In our Case record, for the description, we have the line break (\n) specified.

A screenshot of a computer

Description automatically generated
A screenshot of a computer

Description automatically generated

However, for the email created, we see the line break ignored.

A screenshot of a computer

Description automatically generated

To fix this we might think of applying the below formula by replacing “\n” with “”.

replace(triggerOutputs()?[‘body/description’],’\n’,’
‘)

A screenshot of a computer

Description automatically generated
A screenshot of a computer

Description automatically generated

On triggering our flow after these changes.

A screenshot of a computer

Description automatically generated

We still do not see the line break added in the description of the email.

This is because the ‘/n’ character is ignored by the replace formula.

To fix this we need to first initialize a variable for the new line of type string by hitting/pressing the Enter button for the Value.

A screenshot of a computer

Description automatically generated

Next comes our formula where we will use this variable.

replace(triggerOutputs()?[‘body/description’],variables(‘varNewLine’),’
‘)

A screenshot of a computer

Description automatically generated

Triggering the flow now –

A screenshot of a phone

Description automatically generated

generates the proper email description with line break.

A screenshot of a email form

Description automatically generated

The helpful post – https://tomriha.com/how-to-replace-new-line-n-in-a-power-automate-expression/

Hope it helps..

Advertisements

Free up Storage space – ActivityPointerBase and WorkflowLogBase (Dataverse / Dynamics 365)


Had shared the steps we had followed to reduce the storage space for one of our environments which was a copy of production below a few months back –https://nishantrana.me/2023/09/28/free-up-storage-space-dataverse-dynamics-365/

This time we followed more or less the same steps, the main difference was this time we used our favorite XrmToolBox plugin SQL4CDS to perform the delete operations instead of the bulk deletion job.

However, even after deleting all the Activity type records (except one appointment record which was giving some error on deletion), as shown below, the ActivityPointer was still showing 13 GB of space occupied.

select activitytypecodename,activitytypecode, Count(activitytypecode) as Total
from activitypointer
group by activitytypecode, activitytypecodename
order by Total desc

And the same was true for the WorkflowLogBase, we used a bulk deletion job for deleting the system jobs with status as succeeded which deleted around 1200 records, however running the same query in SQL4CDS showed us around 70K records with status as success.

On trying to run the following query it gave us an “Expected non-empty Guid” error and we could not delete the records.

Eventually, we raised the Support Ticket for it, and the team ran the script in the background to delete/reduce the size of the Activity Pointer and Workflow Log table and eventually we were able to reduce the database usage (we also deleted few other table records)

Before –

After –

A close up of a white background

Description automatically generated

Get more details

Hope it helps..

Advertisements

Use JavaScript to add onchange event to a field in the Business Process Flow


Let us continue our previous post, here we will update the script to add an onchange event to the Identify Sales Team field in the Business Process Flow. Based on the value selected we will make the Develop Proposal field mandatory.

A screenshot of a computer

Description automatically generated

Below is the code we need to add for it.

A screen shot of a computer program

Description automatically generated
function OnLoad(executionContext)
{
	 var formContext = executionContext.getFormContext();
	 formContext.data.process.addOnStageChange(CheckStageAndToggleFieldBPF);
	 CheckStageAndToggleFieldBPF(executionContext);
}

 function CheckStageAndToggleFieldBPF(executionContext) {

        var formContext = executionContext.getFormContext();     
        var activeStage = formContext.data.process.getActiveStage();
        var activeStageId = activeStage.getId();		
        var stagePropose = "3a275c22-fc45-4e89-97fc-41e5ec578743";
     
        if (activeStageId.toLowerCase() === stagePropose) {          
                formContext.getControl("header_process_identifypursuitteam").setDisabled(false);                 
        }
        else {
            formContext.getControl("header_process_identifypursuitteam").setDisabled(true);
        }    

		formContext.getControl("header_process_identifypursuitteam").getAttribute().addOnChange(function(executionContext) {

                if (formContext.getControl("header_process_identifypursuitteam").getAttribute().getValue()) 
				{
                    formContext.getControl("header_process_developproposal").getAttribute().setRequiredLevel("required");
                }
                else 
				{
                    formContext.getControl("header_process_developproposal").getAttribute().setRequiredLevel("none");
                }
            });
  }
  
  
  
  

We can add it to the field if it is in the form also, that will also work the same. However, if we do not have the field on the form we need to add it to the field on the BPF.

On selecting the value completed for Identify Sales Team, we can see the Develop Proposal field being set as mandatory.

A screenshot of a computer

Description automatically generated
A screenshot of a computer

Description automatically generated

Later if we add the same field on the form, or into another stage of the BPF, the onchange event will apply and work for them.

For the field on the form –

A screenshot of a computer

Description automatically generated

Same field in another stage –

A screenshot of a computer

Description automatically generated
A screenshot of a computer screen

Description automatically generated

Hope it helps..

Advertisements

Use the new Associated Grid Control to display details of other tables in subgrids – Model-driven App / Dynamics 365


With the Associated Grid Control we can configure and show up four subgrids in the form, making it a more intuitive and cleaner form layout, with ease of navigation.

Below we are adding the Associated Grid Control component to the Contact’s form.

Here we have specified the Subgrid Tables and Views to begin with.

A screenshot of a computer

Description automatically generated

For the 1st subgrid specified we can set the specific options from the properties pane. Here let us try checking the Show related rows properties for the cases subgrid.

On doing so, we get the below message.

It basically reset the 1st subgrid’s table to Accounts from Case, the rest of the configuration remains unchanged.

A screenshot of a computer

Description automatically generated

Let us change it back to Cases and select the appropriate view.

A screenshot of a contact page

Description automatically generated

Let us save and publish the change.

Now in the Contact form we can see the grid control with 4 different subgrids as configured.

The Active Cases shows the associated cases.

A screenshot of a computer

Description automatically generated

However, that is not the case with other subgrids as they show all the records.

A screenshot of a computer

Description automatically generated

To filter it to show the associated records we need to specify the relationship name while configuring the component.

Let us edit the component.

A screenshot of a computer

Description automatically generated

Below we specified the relationship name for the subgrid 2 i.e Accounts.

A screenshot of a computer

Description automatically generated

As expected, this time we can see Active Accounts filtered to show only those account records where the contact is associated as the primary contact.

A screenshot of a computer
Description automatically generated

Get all the details here

Also check –

Due Open Activities Control – https://nishantrana.me/2023/05/09/due-open-activities-control-dynamics-365/

Notes Control – https://nishantrana.me/2023/05/10/notes-control-dynamics-365/

Attachment Control – https://nishantrana.me/2023/05/08/new-attachment-control-dynamics-365/

OptionSet Wrapper Component – Use OptionSet Wrapper component to show color-coded options on the form

Hope it helps..

Advertisements

New Lead Qualification Experience – Dynamics 365 Sales


To enable the new lead experience, navigate to App Settings >> Lead + opportunity management in the Sales Hub App.

A screenshot of a computer

Description automatically generated

On enabling it, we get the option to specify whether the Account, Contact, and Opportunity records are created automatically or the user (seller) has the option to specify which record to create.

We also see the option to Copilot summarizing the case once a lead is qualified.

For opportunity, if we select Seller, we get an additional option to modify the Opportunity form by adding or removing fields and also the option to allow a maximum of 5 new opportunities during lead qualification.

A screenshot of a computer

Description automatically generated

Clicking on the Add or remove fields link opens the Opportunity qualify lead form for customization.

A screenshot of a computer

Description automatically generated

Let us see it in action.

On clicking the Qualify command, we can see the new Qualify lead dialog opened in the side pane.

It gives us the option to create a new Account, Contact, and/or Opportunity record.

A screenshot of a computer

Description automatically generated

For Account and Contact, we can specify an existing record or select none if we do not want the Account and Contact record to be created.

A screenshot of a computer

Description automatically generated

For opportunity, we can click on edit icon to update the details of the opportunity record to be created. It will open the Opportunity qualify lead form.

A screenshot of a computer

Description automatically generated

Similarly clicking on + New opportunity allows us to specify a value for the new opportunity record.

A screenshot of a computer

Description automatically generated

As we had selected the option of a maximum of 5 opportunities, we got the below message on trying to specify the 6th opportunity record.

“You can’t add more than 5 opportunities.”

A screenshot of a computer

Description automatically generated

Let us click on Qualify.

We can see below details, the link to the records generated, and the summary.

A screenshot of a computer screen

Description automatically generated

Clicking on Finish opens the 1st opportunity record. We can also see the summary added to it.

A screenshot of a computer

Description automatically generated

On setting all the options to Automatic,

A screenshot of a computer

Description automatically generated

we can see the below details in the Qualify lead dialog, all as read-only information.

Get all the details here

Hope it helps..

Advertisements