Prompt & Platform
Connect
HomeTopicsSnippetsDev toolsArticles
Theme
DataverseIntermediate

FetchXML vs OData vs QueryExpression: which one when

Three ways to query Dataverse, side by side. See the same query in each, and learn which to use in plugins, scripts, flows and integrations.

Prerequisites

  • Basic Dataverse knowledge
  • Familiarity with C# or JavaScript helps

What you'll learn

  • Write the same query three ways
  • Pick the right syntax for plugins, JavaScript and flows
  • Know the limits: paging, aggregates and joins
On this page
  1. The same query, three ways
  2. When to use each
  3. Practical tips

Dataverse gives you several ways to ask for data. They all return the same rows, but each fits a different place in your solution.

The same query, three ways

Goal: the 10 newest active contacts, with name and email.

FetchXML
<fetch top="10">
  <entity name="contact">
    <attribute name="fullname" />
    <attribute name="emailaddress1" />
    <filter>
      <condition attribute="statecode" operator="eq" value="0" />
    </filter>
    <order attribute="createdon" descending="true" />
  </entity>
</fetch>
OData
GET [org]/api/data/v9.2/contacts?$select=fullname,emailaddress1&$filter=statecode eq 0&$orderby=createdon desc&$top=10
C#
var query = new QueryExpression("contact")
{
    ColumnSet = new ColumnSet("fullname", "emailaddress1"),
    TopCount = 10
};
query.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);
query.AddOrder("createdon", OrderType.Descending);

var contacts = service.RetrieveMultiple(query).Entities;

When to use each

OptionBest forWatch out for
FetchXMLAggregates, complex joins, reusing a view's queryVerbose; build it with a tool
OData (Web API)JavaScript, external apps, Power AutomateSome joins and aggregates are harder
QueryExpressionC# plugins and console appsStrongly typed, but more code

Practical tips

  • Copy, don't write. Build FetchXML in Advanced Find or with a tool like FetchXML Builder, then paste it. Use the formatter on the Dev tools page to tidy it up.
  • Aggregates need FetchXML. Sums, counts and group-by are simplest with aggregate="true".
  • Paging matters. Queries return 5,000 rows per page by default. Use paging cookies (FetchXML) or @odata.nextLink (Web API) when you need everything.
  • In flows, List rows accepts both a FetchXML query and OData-style filter. Use FetchXML when you need joins.
J / K next or previous article

Jagadeesan P

Found this useful? I share new guides on LinkedIn.

Follow