Build Efficient Flows Using Filter Expression in Microsoft Dataverse Trigger

One of the key best practices for creating an efficient automated flow in Power Automate (Dynamics 365 or Common Data Service) is to properly set the options on the trigger of the flow to minimise unnecessary triggering and reduce execution time. As specified in a guide to building enterprise-ready flows, you should always set attribute filters unless you are interested in any change to the record. Aside from the attribute filtering, there is also a Filter Expression parameter option in the Common Data Service (current environment) connector that you can use to filter records to process.

In this blog post, you will learn how to use the following functionalities in Power Automate.
  • Filter Expression to filter further based on the value of the record and run the flow only for certain criteria
  • Trigger Conditions to filter as an alternative option, what are the differences and when to use it
  • Peek code option to get the expression of the Dynamic content
  • Guard conditions to increase the readability of the flow
Flow Filter Expression

Let’s identify a few scenarios where we can apply our filtering and how it affects the efficiency of the process.
Scenario 1: The Case entity has multiple statuses (In Progress, On Hold, Waiting for Details, Researching, Problem Solved, Cancelled, etc.) and an automated flow needs to trigger when the Case is cancelled.

Scenario 2: There are multiple types of Contacts based on the custom OptionSet values (Client, Family, Professional, Employee) and an automated flow needs to trigger when the Employee Contact record is deleted.

Scenario 3: An automated flow needs to trigger when the Account record is created and there is no value in Parent Account lookup.

If no filter expression is used in the scenarios above, the automated flow will trigger regardless of the value of the field and the unnecessary flow runs need to be cancelled with a condition check. Let's see how we can optimise our flow and use Filter Expression or Trigger Conditions so that the flow will only run based on the criteria we want.

Sample Scenario: An automated flow needs to trigger when the Account record is deactivated.

This is how it will look like in a workflow designer if the Sample Scenario is solved using the classic workflow process.
Classic Workflow

As a Dynamics 365 consultant who started working with Microsoft Dynamics CRM workflow designer, the flows that I created initially were based on how I would design it using the classic workflow designer.
Account Status Condition Check

Over time, as I learn more and more, I managed to improve the design of my flow gradually. One of the things I learnt was how to avoid nested conditionals by using Guard Conditions after coming across the blog post by Jonas Rapp. So instead of the flow above, the flow can be re-created in the following manner to increase its readability.
Account Status Check Guard Condition

However, the flow still runs whenever the status of the Account record is changed to either Active or Inactive and unnecessary Canceled flow runs are showing up in the run history. In Common Data Service (current environment) connector trigger, there is a parameter called Filter Expression which accepts an OData style filter expression. By using that parameter, we can control the trigger to only fire if the filter expression evaluates to true.
Flow Filter Expression
By adding the filter expression in the above sample, the condition check in the flow is no longer necessary and the flow run history only shows the valid triggers according to the requirement.

If you are not familiar with OData style filter expression, you can also use the FetchXML Builder tool as mentioned in the other blog post. You can also learn more details about the Filter Expression in this video by Matt Collins-Jones.

Using the Filter Expression to filter the CDS trigger is recommended because most of those who use the Filter Query in the List records CDS action and those who query data using the Web API with filter property are already familiar with it.

Alternative Solution: Trigger Conditions

Even though Common Data Service (current environment) connector is the recommended one, there might be some use cases where the older "Common Data Service" connector has to be used instead of the (current environment) one.

There is no Filter Expression parameter in the old CDS connector trigger and in those cases, the Trigger Conditions can be used to filter the CDS trigger. Trigger Conditions is not specific to the CDS connector and it can be used in the trigger step of any other connectors too.

To add the Trigger Conditions, click on the ellipsis of the trigger and select Setting.
Flow Trigger Conditions

Then, fill up the Trigger Conditions using the flow expression.
It needs to start with @ symbol followed by the flow expression using triggerOutputs.
Trigger Conditions

Multiple trigger conditions can be added if the flow needs to trigger only when ALL of the conditions are met.
If the flow can trigger as long as one of the conditions are met, or expression can be used.
 @or(equals(triggerOutputs()?['body/statecode'], 1), equals(triggerOutputs()?['body/name'], 'Test Account'))  
To learn more about the Trigger Conditions, check out this vlog by Reza Dorrani.

This approach might be easier for those who are proficient in flow expression but not familiar with OData style filter expression.
The flow checker can also validate if the syntax of the flow expression is incorrect (e.g. missing @, wrong spelling of the expression or missing parentheses, etc.). But it will not validate if the variable in the expression is not valid. There is no way to select from the list of Dynamic content and the whole flow expression needs to be typed in manually.

🛈 Bonus Tip

If you do not know what the expression for the Dynamic content is, add a Compose step and populate with the required Dynamic content. Then, use the peek code option to get the expression of the Dynamic content.

Compose Dynamics Content

Peek Code

Since the Trigger Conditions can be used to filter based on the outputs of the trigger step, one of the advantages over Filter Expression is that a flow trigger can be filtered based on
  • the label of the Optionset field. This is not recommended but technically possible (e.g. trigger the flow only if the record status label is "Inactive")
 @equals(triggerOutputs()?['body/_statecode_label'], 'Inactive')   

  • the name value of the lookup field (e.g. trigger the flow only when the record is assigned to the team)
 @equals(triggerOutputs()?['body/_ownerid_type'], 'teams')  

For the same reason, Trigger Conditions cannot be used to filter for the record Delete event because the outputs of the Delete trigger step do not contain any useful information. (If you'd like to see more information in the outputs of the Delete trigger, go and vote this Power Automate Idea)
CDS Delete Output

It is important not only to set attribute filters on the trigger to minimise unnecessary triggering but also to set the filter conditions of the trigger using Filter Expression with OData style filter expression (recommended way) or Trigger Conditions with flow expression (alternative way). By filtering the condition of the flow triggers, we can 
  • prevent the flow from triggering unnecessarily
  • save a lot of API calls
  • have a cleaner flow run history


  1. Hi Linn,
    Truly appreciate the content that you are sharing.
    I do have a query regarding filtering attributes.
    My scenario is that I have a flow which gets triggered for multiple filtering attributes. Is there a way identity which filtering attribute triggered the flow?
    Please let me know your views on this.

    1. Hi Sagar,
      Glad to hear that my content is helpful.

      I am afraid there is no easy way to identify the filtering attribute which triggers the flow. The workaround solution would be creating multiple flows with different filtering attributes which call the common child flow for the rest of the steps.


Post a Comment

Popular Posts