Edit

Share via


How to: Connect your code app to Dataverse

This guide helps developers use the Power Apps client library for code apps to connect their code app to Microsoft Dataverse.

Prerequisites

Steps

  1. Ensure you're connected to your environment using PAC CLI.

  2. Use the pac code add-data-source command to add Dataverse as a data source to your code app.

    pac code add-data-source -a dataverse -t <table-logical-name>
    

    Replace <table-logical-name> with the logical name of the Dataverse table you want to connect to.

Supported scenarios

The Power Apps client library for code apps supports the following scenarios when you connect to Dataverse:

  • Add Dataverse entities to code apps.

  • Retrieve formatted values (labels) for option sets option values.

  • Get metadata for Dataverse tables.

  • Work with lookups. Currently, you need to use the guidance to associate with a single-valued navigation property or associate records on create when working with lookups. A dedicated how-to guide is coming soon. The Power Apps team is actively working to make lookups easier to use in code apps.

  • Image and file upload and download (preview). When you add Dataverse as a data source by using the npm-based cli, the generated functions are part of src/generated/services.

  • Perform CRUD operations:

    • Create
    • Retrieve
    • RetrieveMultiple
    • Update
    • Delete
  • Delegation for:

    • Filter
    • Sort
    • Top queries
  • Paging support.

Tip

Looking for a complete working example? The Dataverse demo app demonstrates all the patterns covered in this article - CRUD operations, lookup fields, image and file upload and download, and generated services - in a React/TypeScript app you can explore and extend. To run the app yourself, follow the setup instructions in PowerAppsCodeApps/samples/Dataverse/DEVELOPMENT.md to configure it for your environment.

Set up your code app

Before performing create, read, update, and delete (CRUD) operations in your code app, import the required types and services.

When you add a data source, the system automatically generates model and service files and places them in the /generated/services/ folder. For example, if you add the built-in Accounts table as a data source, the following files are created:

  • AccountsModel.ts – Defines the data model for the Accounts table.
  • AccountsService.ts – Provides service methods for interacting with the Accounts data.

You can import and use these files in your code like this:

import { AccountsService } from './generated/services/AccountsService';
import type { Accounts } from './generated/models/AccountsModel';

Create records

Use the generated model types and service methods to create new Dataverse records from your code app.

  1. Create the record object using the generated model

    The generated models reflect the schema of your Dataverse table. Use them to create record objects.

    Note

    When creating a record, exclude system-managed or read-only columns such as primary keys and ownership fields. To understand which columns are read-only, see Browse table definitions in your environment. For example, in the Accounts table, don't include the following fields:

    • accountid
    • ownerid
    • owneridname
    • owneridtype
    • owneridyominame

    Form a record with only the fields you want to populate. For example, for the Accounts entity:

    
    const newAccount = {
       name: "New Account"
       statecode: 0,
       accountnumber: "ACCOO1"
       ...
    };
    
  2. Submit the record using the generated service

    Use the functions in the generated service file to submit your record. For example, for the Accounts entity:

    try {
    const result = await AccountsService.create(newAccount as Omit<Accounts, 'accountid'>);
    
    if (result.data) {
    console.log('Account created:', result.data);
    return result.data;
    }
    } catch (err) {
    console.error('Failed to create account:', err);
    throw err;
    };
    

Read data

You can retrieve a single record or compose a query to return multiple records.

Retrieve a single record

To retrieve a single record, you need its primary key (for example, accountid).

const accountId = "<00000000-0000-0000-0000-000000000000>"; // Replace with actual ID value

try {
      const result = await AccountsService.get(accountId);
      if (result.data) {
            console.log('Account retrieved:', result.data);
      }
} catch (err) {
      console.error('Failed to retrieve account:', err);
}

Retrieve multiple records

To retrieve all records from a Dataverse table, use the getAll method:

try {
   const result = await AccountsService.getAll();
   if (result.data) {
         const accounts = result.data;
         console.log(`Retrieved ${accounts.length} accounts`);
   }
} catch (err) {
   console.error('Failed to retrieve accounts:', err);
}

The getAll method accepts an optional parameter that implements the IGetAllOptions interface. Use these options to customize the query:

interface IGetAllOptions {
   maxPageSize?: number;    // Maximum number of records per page
   select?: string[];       // Specific fields to retrieve
   filter?: string;         // OData filter string
   orderBy?: string[];     // Fields to sort by
   top?: number;           // Maximum number of records to retrieve
   skip?: number;          // Number of records to skip
   skipToken?: string;     // Token for pagination
}

Important

Always limit the number of columns you retrieve by using the select parameter.

Here's an example with multiple options:

const fetchAccounts = async () => {
const options: IGetAllOptions = {
      select: ['name', 'accountnumber', 'address1_city'],
      filter: "address1_country eq 'USA'",
      orderBy: ['name asc'],
      top: 50
};

try {
      const result = await AccountsService.getAll(options);
      return result.data || [];
} catch (err) {
      console.error('Failed to fetch accounts:', err);
      return [];
}
};

Update records

To update a record, you need:

  1. The record's primary key value. For example, with the account table, the accountid value.
  2. The changes you want to make.

Important

When you update a record, only include the properties you're changing in the request. If you set some changed properties of a record that you previously retrieved and include that data in your request, you update all properties even though their values didn't change. False updates like these can trigger business logic that expects the values changed, or can corrupt auditing data to indicate that someone changed data that didn't change.

This example updates the name and telephone1 properties of the account record:

const accountId = "<your-account-guid>";
const changes = {
      name: "Updated Account Name",
      telephone1: "555-0123"
};

try {
      await AccountsService.update(accountId, changes);
      console.log('Account updated successfully');
} catch (err) {
      console.error('Failed to update account:', err);
}

Delete records in Dataverse

To delete a record, you need the record's primary key value. For example, with the account table, the accountid value.

For example:

const accountId = "<00000000-0000-0000-0000-000000000000>"; // Replace with actual ID value

try {
  await AccountsService.delete(accountId);
  console.log('Account deleted successfully');
} catch (err) {
  console.error('Failed to delete account:', err);
}

Unsupported scenarios

The following features aren't yet supported:

  • Polymorphic lookups
  • Dataverse actions and functions
  • Deleting Dataverse datasources through PAC CLI
  • Schema definition (entity metadata) CRUD
  • FetchXML support
  • Alternate key support