Udostępnij przez


retrieveMultipleRecords (dokumentacja interfejsu API klienta)

Pobiera kolekcję rekordów tabeli.

Składnia

Xrm.WebApi.retrieveMultipleRecords(entityLogicalName, options, maxPageSize).then(successCallback, errorCallback);

Parametry

Name Typ Wymagane Description
entityLogicalName Sznurek Tak Nazwa logiczna tabeli rekordów, które chcesz pobrać. Na przykład: account.
options Sznurek Nie. Opcje zapytania systemu OData lub zapytanie FetchXML w celu pobrania danych. Zobacz opcje
maxPageSize Number Nie. Określ liczbę dodatnią wskazującą liczbę rekordów tabeli, które mają być zwracane na stronę. Jeśli nie określisz tego parametru, wartość zostanie domyślnie ustawiona na maksymalny limit 5000 rekordów dla tabel standardowych, 500 dla tabel elastycznych.

Jeśli liczba pobieranych rekordów jest większa niż określona maxPageSize wartość lub maksymalny limit dla typu tabeli, nextLink kolumna w zwracanym obiekcie obietnicy będzie zawierać link do pobierania rekordów.
successCallback Funkcja Nie. Funkcja do wywołania podczas pobierania rekordów tabeli. Zobacz wartość zwracaną
errorCallback Funkcja Nie. Funkcja wywoływana, gdy operacja zakończy się niepowodzeniem. Obiekt z następującymi właściwościami jest przekazywany:
- errorCode:Numer. Kod błędu jako dodatnia liczba dziesiętna. Na przykład kod błędu udokumentowany jako 0x80040333 zostanie zwrócony jako 2147746611.
- message:Struna. Komunikat o błędzie opisujący problem.

Opcje

Obsługiwane są następujące opcje zapytań systemowych: $select, , $filter$top, $expand, i $orderby.

Użyj opcji zapytania systemowego $expand , aby kontrolować, jakie dane z powiązanych tabel są zwracane. Jeśli po prostu dołączysz nazwę właściwości nawigacji, otrzymasz wszystkie właściwości powiązanych rekordów. Właściwości zwracane dla powiązanych rekordów można ograniczyć przy użyciu $select opcji zapytania systemowego w nawiasach po nazwie właściwości nawigacji. Użyj tej opcji zarówno dla właściwości nawigacji jednowartościowych , jak i kolekcji . Należy pamiętać, że w przypadku trybu offline obsługujemy tylko opcję zagnieżdżonych $select wewnątrz elementu $expand.

Aby określić zapytanie FetchXML, użyj fetchXml kolumny, aby określić zapytanie.

Uwaga / Notatka

Zawsze należy użyć $selectopcji zapytania systemowego, aby ograniczyć właściwości zwracane dla rekordu tabeli przez dołączenie rozdzielanej przecinkami listy nazw właściwości. Jest to ważne najlepsze rozwiązanie dotyczące wydajności. Jeśli właściwości nie zostaną określone przy użyciu metody $select, zostaną zwrócone wszystkie właściwości.

Opcje kwerendy określa się, zaczynając od ?. Można również określić wiele opcji zapytania systemowego, używając polecenia & , aby oddzielić opcje zapytania.

Po określeniu ciągu zapytania OData dla parametru options zapytanie powinno być zakodowane dla znaków specjalnych.

Po określeniu zapytania FetchXML dla parametru options zapytanie nie powinno być kodowane.

Zobacz Przykłady , aby zobaczyć, jak można zdefiniować parametr dla options różnych scenariuszy pobierania.

Wartość zwracana

W przypadku powodzenia zwraca obiekt obietnicy do successCallback obiektu z następującymi właściwościami:

Name Typ Description
entities Tablica obiektów JSON Każdy obiekt reprezentuje pobrany rekord tabeli zawierający kolumny i ich wartości jako key: value pary. Identyfikator rekordu tabeli jest domyślnie pobierany
nextLink Sznurek (opcjonalnie) Jeśli liczba pobieranych rekordów jest większa niż wartość określona w parametrze maxPageSize w żądaniu, zwraca adres URL, aby zwrócić następną stronę rekordów.
fetchXmlPagingCookie (opcjonalnie) W przypadku operacji opartej na retrieveMultipleRecords fetchXml z stronicowaniem, gdzie łączna liczba rekordów jest większa niż wartość stronicowania, ten atrybut zwraca plik cookie stronicowania, który może być używany do kolejnej operacji pobieraniaXml w celu pobrania następnej strony rekordów.

Nieobsługiwane typy atrybutów dla opcji zapytań OData w trybie offline dla urządzeń przenośnych

Następujące typy kolumn nie są obsługiwane podczas wykonywania Xrm.WebApi.retrieveMultipleRecords operacji z opcjami ciągu zapytania OData (na przykład $select i $filter) w trybie offline dla urządzeń przenośnych. Należy użyć narzędzia FetchXML, jeśli typ atrybutu, z którym chcesz pracować, znajduje się na tej liście nieobsługiwanych typów atrybutów.

  • MultiSelectPicklist
  • File
  • Image
  • ManagedProperty
  • CalendarRules
  • PartyList
  • Virtual

Nieobsługiwane funkcje w trybie offline dla urządzeń przenośnych

Następujące funkcje nie są obsługiwane w trybie offline dla urządzeń przenośnych:

  • Funkcje grupowania i agregacji

Obsługiwane operacje filtrowania na typ atrybutu w trybie offline dla urządzeń przenośnych przy użyciu narzędzia FetchXML

Następujące operacje są obsługiwane dla wszystkich typów atrybutów podczas pracy z FetchXML:

  • Równa się (eq)
  • Nie równa się (neq)
  • Null (null)
  • Nie ma wartości null (not-null)

W poniższej tabeli wymieniono więcej operacji obsługiwanych dla każdego typu atrybutu:

Typ atrybutu Obsługiwane operacje
BigInt, Decimal, Double, Integer Większe niż (gt)
Większe niż lub równe (gte)
Mniejsze niż (lt)
Mniejsze niż lub równe (lte)
Wartość logiczna, klient W (in)
Nie w (not-in)
EntityName, Picklist, State, Status Podobnie jak (like)
Nie lubię (not-like)
Zaczyna się od (begins-with)
Nie zaczynaj się od (not-begin-with)
Kończy się na (ends-with)
Nie kończy się na (not-end-with)
W (in)
Nie w (not-in)
Guid, Lookup W (in)
Nie w (not-in)
Równa się identyfikatorowi użytkownika (eq-userid)
Nie równa się identyfikatorowi użytkownika (ne-userid)
Pieniądze Większe niż (gt)
Większe niż lub równe (gte)
Mniejsze niż (lt)
Mniejsze niż lub równe (lte)
W (in)
Nie w (not-in)
Właściciel W (in)
Nie w (not-in)
Równa się identyfikatorowi użytkownika (eq-userid)
Nie równa się identyfikatorowi użytkownika (ne-userid)
Równa się użytkownikowi lub zespołowi (eq-useroruserteams)
Sznurek Podobnie jak (like)
Nie lubię (not-like)
Zaczyna się od (begins-with)
Nie zaczynaj się od (not-begin-with)
Kończy się na (ends-with)
Nie kończy się na (not-end-with)
DateTime Włączone lub po (on-or-after)
Włączone (on)
W dniu lub przed (on-or-before)
Dzisiaj (today)
Jutro (tomorrow)
Wczoraj (yesterday)
Następne siedem dni (next-seven-days)
Ostatnie siedem dni (last-seven-days)
Następny tydzień (next-week)
Ostatni tydzień (last-week)
W tym tygodniu (this-week)
Następny miesiąc (next-month)
Ostatni miesiąc (last-month)
Ten miesiąc (this-month)
Następny rok (next-year)
Ostatni rok (last-year)
W tym roku (this-year)
Ostatnie X dni (last-x-days)
Następne X dni (next-x-days)
Ostatnie X Tygodnie (last-x-weeks)
Następne X Tygodnie (next-x-weeks)
Ostatnie X miesięcy (last-x-months)
Następne X miesięcy (next-x-months)
Ostatnie X lat (last-x-years)
Następne X lat (next-x-years)
Większe niż (gt)
Większe niż lub równe (gte)
Mniejsze niż (lt)
Mniejsze niż lub równe (lte)

Przykłady

Większość scenariuszy/przykładów wymienionych w artykule Query Data using the Web API (Dane zapytań przy użyciu internetowego interfejsu API ) można osiągnąć przy użyciu metody retrieveMultipleRecords . Poniżej wymieniono niektóre przykłady.

Podstawowe pobieranie wielu

W tym przykładzie kwerenda zestawu tabel accounts i używa $select opcji zapytania systemowego i $top , aby zwrócić właściwość name dla pierwszych trzech kont:

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$top=3").then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }                    
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Podstawowe pobieranie wielu za pomocą narzędzia FetchXML

W tym przykładzie jest wysyłana kwerenda do account jednostki przy użyciu narzędzia fetchXML.

var fetchXml = "?fetchXml=<fetch><entity name='account'><attribute name='accountid'/><attribute name='name'/></entity></fetch>";

Xrm.WebApi.retrieveMultipleRecords("account", fetchXml).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }                    

        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Pobieranie lub filtrowanie według właściwości odnośnika

W przypadku większości właściwości nawigacji z jedną wartością można znaleźć obliczoną właściwość tylko do odczytu, która używa następującej konwencji nazewnictwa: _<name>_value gdzie <name> jest nazwą właściwości nawigacji jednowartościowej. Do celów filtrowania można również użyć określonej wartości właściwości nawigacji jednowartościowej. Jednak w przypadku klientów mobilnych w trybie offline te opcje składni nie są obsługiwane, a nazwa właściwości nawigacji o pojedynczej wartości powinna być używana zarówno do pobierania, jak i filtrowania. Ponadto porównanie właściwości nawigacji z wartością null nie jest obsługiwane w trybie offline.

Więcej informacji: Właściwości odnośnika

Oto przykłady kodu dla obu scenariuszy:

W przypadku scenariusza online (połączonego z serwerem)

W tym przykładzie kwerenda zestawu tabel kont i używa $select opcji zapytania systemowego i $filter , aby zwrócić nazwę i właściwość primarycontactid dla kont, które mają określony kontakt podstawowy:

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name,_primarycontactid_value&$filter=primarycontactid/contactid eq a0dbf27c-8efb-e511-80d2-00155db07c77").then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }                    
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

W przypadku scenariusza trybu offline dla urządzeń przenośnych

W tym przykładzie kwerenda zestawu tabel kont i używa $select opcji zapytania systemowego i $filter , aby zwrócić nazwę i właściwość primarycontactid dla kont, które mają określony kontakt podstawowy podczas pracy w trybie offline:

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name,primarycontactid&$filter=primarycontactid eq a0dbf27c-8efb-e511-80d2-00155db07c77").then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }                    
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Używanie narzędzia FetchXML do pobierania lub filtrowania według właściwości odnośnika (scenariusz online i offline)

Możesz użyć parametru FetchXML w trybie online lub offline, aby pobrać name właściwość i primarycontactid dla rekordów kont, które mają kontakt podstawowy zgodny z warunkiem:

var fetchXml = `?fetchXml=
    <fetch>
       <entity name='account'>
          <attribute name='name'/>
          <attribute name='primarycontactid'/>
          <link-entity name='contact' from='contactid' to='primarycontactid'>
             <filter type='and'>
                <condition attribute='lastname' operator='eq' value='Contoso'/>
             </filter>
          </link-entity>
       </entity>
    </fetch>`;

Xrm.WebApi.retrieveMultipleRecords("account", fetchXml).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }                    

        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Określ liczbę tabel, które mają być zwracane na stronie

W poniższym przykładzie pokazano użycie parametru maxPageSize w celu określenia liczby rekordów (3) do wyświetlenia na stronie.

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name", 3).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }
        console.log("Next page link: " + result.nextLink);
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

W tym przykładzie zostaną wyświetlone trzy rekordy i link do następnej strony. Oto przykładowe dane wyjściowe z konsoli w narzędziach deweloperskich przeglądarki:

{@odata.etag: "W/"1035541"", name: "A. Datum", accountid: "475b158c-541c-e511-80d3-3863bb347ba8"}
@odata.etag: "W/"1035541""accountid: "475b158c-541c-e511-80d3-3863bb347ba8"name: "A. Datum"__proto__: Object
VM5595:4 
{@odata.etag: "W/"947306"", name: "Adventure Works", accountid: "a8a19cdd-88df-e311-b8e5-6c3be5a8b200"}
VM5595:4 
{@odata.etag: "W/"1033754"", name: "Alpine Ski House", accountid: "aaa19cdd-88df-e311-b8e5-6c3be5a8b200"}
VM5595:6 
Next page link: [Organization URI]/api/data/v9.0/accounts?$select=name&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257bAAA19CDD-88DF-E311-B8E5-6C3BE5A8B200%257d%2522%2520first%253d%2522%257b475B158C-541C-E511-80D3-3863BB347BA8%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E

Użyj części zapytania w adresie URL nextLink we właściwości jako wartości parametru options w kolejnym wywołaniu retrieveMultipleRecords , aby zażądać następnego zestawu rekordów. Nie zmieniaj ani nie dołączaj kolejnych opcji zapytania systemowego do wartości. Dla każdego kolejnego żądania dla większej liczby stron należy użyć tej samej maxPageSize wartości użytej w oryginalnym żądaniu pobierania wielu. Ponadto buforuj zwrócone wyniki lub wartość właściwości nextLink, aby można było zwrócić wcześniej pobrane strony.

Aby na przykład uzyskać następną stronę rekordów, przekażemy część nextLink zapytania adresu URL do parametru options :

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257bAAA19CDD-88DF-E311-B8E5-6C3BE5A8B200%257d%2522%2520first%253d%2522%257b475B158C-541C-E511-80D3-3863BB347BA8%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E", 3).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }
        console.log("Next page link: " + result.nextLink);
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Spowoduje to zwrócenie następnej strony zestawu wyników:

{@odata.etag: "W/"1035542"", name: "Blue Yonder Airlines", accountid: "aca19cdd-88df-e311-b8e5-6c3be5a8b200"}
VM5597:4 
{@odata.etag: "W/"1031348"", name: "City Power & Light", accountid: "aea19cdd-88df-e311-b8e5-6c3be5a8b200"}
VM5597:4 
{@odata.etag: "W/"1035543"", name: "Coho Winery", accountid: "b0a19cdd-88df-e311-b8e5-6c3be5a8b200"}
VM5597:6 
Next page link: [Organization URI]/api/data/v9.0/accounts?$select=name&$skiptoken=%3Ccookie%20pagenumber=%223%22%20pagingcookie=%22%253ccookie%2520page%253d%25222%2522%253e%253caccountid%2520last%253d%2522%257bB0A19CDD-88DF-E311-B8E5-6C3BE5A8B200%257d%2522%2520first%253d%2522%257bACA19CDD-88DF-E311-B8E5-6C3BE5A8B200%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E

Ważne

Wartość nextLink właściwości jest zakodowana za pomocą identyfikatora URI. Jeśli kodujesz wartość przed jej wysłaniem, informacje o plikach cookie XML w adresie URL spowodują błąd.

Przykład FetchXML (scenariusz online)

W poniższym przykładzie pokazano użycie count parametru FetchXML w celu określenia liczby rekordów (3) do wyświetlenia na stronie.

Uwaga / Notatka

Plik cookie stronicowania FetchXML jest zwracany tylko w przypadku operacji online retrieveMultipleRecords . (Xrm.WebApi.online). Nie jest obsługiwany w trybie offline.

var fetchXml = "?fetchXml=<fetch count='3'><entity name='account'><attribute name='accountid'/><attribute name='name'/></entity></fetch>";

Xrm.WebApi.online.retrieveMultipleRecords("account", fetchXml).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }          

        console.log("Paging cookie: " + result.fetchXmlPagingCookie);

        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

W tym przykładzie zostaną wyświetlone trzy rekordy i zwróci plik cookie stronicowania FetchXML, aby pobrać wyniki następnej strony, jeśli istnieje więcej rekordów należących do zestawu wyników. Oto przykładowe dane wyjściowe z konsoli w narzędziach deweloperskich przeglądarki:

{
   "entities": [
      {
         "@odata.etag": "W/\"1035542\"",
         "accountid": "aca19cdd-88df-e311-b8e5-6c3be5a8b200",
         "name": "Blue Yonder Airlines"
      },
      {
         "@odata.etag": "W/\"1031348\"",
         "accountid": "aea19cdd-88df-e311-b8e5-6c3be5a8b200",
         "name": "City Power & Light"
      },
      {
         "@odata.etag": "W/\"1035543\"",
         "accountid": "b0a19cdd-88df-e311-b8e5-6c3be5a8b200",
         "name": "Coho Winery"
      }
   ],
   "fetchXmlPagingCookie": "<cookie pagenumber=\"2\" pagingcookie=\"%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b0748C6EC-55A8-EB11-B1B5-000D3AFEF6FA%257d%2522%2520first%253d%2522%257bFC47C6EC-55A8-EB11-B1B5-000D3AFEF6FA%257d%2522%2520%252f%253e%253c%252fcookie%253e\" istracking=\"False\" />"
}

Możemy użyć elementu , fetchXmlPagingCookie jak pokazano w poniższym przykładzie, aby pobrać duże zestawy wyników z stronicowaniem.

function CreateXml(fetchXml, pagingCookie, page, count) {
  var domParser = new DOMParser();
  var xmlSerializer = new XMLSerializer();

  var fetchXmlDocument = domParser.parseFromString(fetchXml, "text/xml");

  if (page) {
    fetchXmlDocument
      .getElementsByTagName("fetch")[0]
      .setAttribute("page", page.toString());
  }

  if (count) {
    fetchXmlDocument
      .getElementsByTagName("fetch")[0]
      .setAttribute("count", count.toString());
  }

  if (pagingCookie) {
    var cookieDoc = domParser.parseFromString(pagingCookie, "text/xml");
    var innerPagingCookie = domParser.parseFromString(
      decodeURIComponent(
        decodeURIComponent(
          cookieDoc
            .getElementsByTagName("cookie")[0]
            .getAttribute("pagingcookie")
        )
      ),
      "text/xml"
    );
    fetchXmlDocument
      .getElementsByTagName("fetch")[0]
      .setAttribute(
        "paging-cookie",
        xmlSerializer.serializeToString(innerPagingCookie)
      );
  }

  return xmlSerializer.serializeToString(fetchXmlDocument);
}

function retrieveAllRecords(entityName, fetchXml, page, count, pagingCookie) {
  if (!page) {
    page = 0;
  }

  return retrievePage(entityName, fetchXml, page + 1, count, pagingCookie).then(
    function success(pageResults) {
      if (pageResults.fetchXmlPagingCookie) {
        return retrieveAllRecords(
          entityName,
          fetchXml,
          page + 1,
          count,
          pageResults.fetchXmlPagingCookie
        ).then(
          function success(results) {
            if (results) {
              return pageResults.entities.concat(results);
            }
          },
          function error(e) {
            throw e;
          }
        );
      } else {
        return pageResults.entities;
      }
    },
    function error(e) {
      throw e;
    }
  );
}

function retrievePage(entityName, fetchXml, pageNumber, count, pagingCookie) {
  var fetchXml =
    "?fetchXml=" + CreateXml(fetchXml, pagingCookie, pageNumber, count);

  return Xrm.WebApi.online.retrieveMultipleRecords(entityName, fetchXml).then(
    function success(result) {
      return result;
    },
    function error(e) {
      throw e;
    }
  );
}

var count = 3;
var fetchXml =
  '<fetch><entity name="account"><attribute name="accountid"/><attribute name="name"/></entity></fetch>';

retrieveAllRecords("account", fetchXml, null, count, null).then(
  function success(result) {
    console.log(result);

    // perform additional operations on retrieved records
  },
  function error(error) {
    console.log(error.message);
    // handle error conditions
  }
);

Użyj opcji $expand zapytania systemowego we właściwościach nawigacji, aby kontrolować dane zwracane z powiązanych tabel. W poniższym przykładzie pokazano, jak pobrać kontakt dla wszystkich rekordów konta. W przypadku powiązanych rekordów kontaktów pobieramy tylko contactid elementy i fullname:

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$top=3&$expand=primarycontactid($select=contactid,fullname)", 3).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }        
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Powyższy fragment kodu zwraca wynik ze schematem, na przykład:

{
   "entities": [
      {
         "@odata.etag": "W/\"1459919\"",
         "name": "Test Account",
         "accountid": "119edfac-19c6-ea11-a81a-000d3af5e732",
         "primarycontactid": {
            "contactid": "6c63a1b7-19c6-ea11-a81a-000d3af5e732",
            "fullname": "Test Contact"
         }
      }
   ]
}

Uwaga / Notatka

Podobnie jak w scenariuszu online, użyj opcji zapytania systemu $expand , aby pobrać dane z powiązanych tabel w trybie offline. Jednak relacje wiele-do-wielu nie są obsługiwane w trybie offline.

Przestarzała metoda dla scenariusza trybu offline dla urządzeń przenośnych

Uwaga / Notatka

Element @odata.nextLink jest przestarzały w scenariuszach trybu offline dla urządzeń przenośnych. Mimo że nadal jest obsługiwana w przypadku istniejących dostosowań, nie zaleca się już używania go.

Operacja $expand offline zwraca adnotację zawierającą @odata.nextLink informacje o sposobie uzyskiwania informacji o powiązanym rekordzie. Używamy parametru id, entityTypei options tej adnotacji, aby skonstruować co najmniej jedno dodatkowe Xrm.WebApi.offline.retrieveRecord żądania. Poniższy fragment kodu zawiera kompletny przykład tego, jak to zrobić:

Xrm.WebApi.offline.retrieveMultipleRecords("account", "?$select=name&$top=3&$expand=primarycontactid($select=contactid,fullname)").then(function(resultSet) {
    /**
     *  resultSet has a structure like:
     *  {
     *      "entities": [
     *          {
     *              "accountid": "119edfac-19c6-ea11-a81a-000d3af5e732",
     *              "name": "Test Account",
     *              "primarycontactid@odata.nextLink": {
     *                  "API": "{Xrm.Mobile.offline}.{retrieveRecord}",
     *                  "id": "119edfac-19c6-ea11-a81a-000d3af5e732",
     *                  "entityType": "account",
     *                  "options": "?$select=accountid&$expand=primarycontactid($select=contactid,fullname)&$getOnlyRelatedEntity=true"
     *              },
     *              "primarycontactid": {}
     *          }
     *      ]
     *  }
     *
     *  Notice the empty `primarycontactid` property but an additional `primarycontactid@odata.nextLink` 
     *  annotation that lets us know how to get to the linked data that we need.
     **/

    var promises = resultSet.entities.map(function(outerItem) {
        // We do a retrieveRecord() for every item in the result set of retrieveMultipleRecords() and then
        // combine the results into the retrieveMultipleRecords() result set itself.
       return Xrm.WebApi.offline.retrieveRecord(
           outerItem["primarycontactid@odata.nextLink"].entityType, 
           outerItem["primarycontactid@odata.nextLink"].id,
           outerItem["primarycontactid@odata.nextLink"].options
        ).then(function(innerResult) {            
            if (innerResult.value.length === 0) {
                return outerItem;
            }
            outerItem.primarycontactid = innerResult.value[0];
            return outerItem;
        });
    });

    return Promise.all(promises);
}).then(function(allResults) {
    for (var i = 0; i < allResults.length; i++) {
        console.log(allResults[i]);
    }
    // perform additional operations on retrieved records
}, function(error) {
    console.error(error);
    // handle error conditions
});

Aby uzyskać więcej przykładów pobierania wielu rekordów przy użyciu internetowego interfejsu API, zobacz Query Data using the Web API (Wykonywanie zapytań o dane przy użyciu internetowego interfejsu API).

Wykonywanie zapytań o dane przy użyciu internetowego interfejsu API
Xrm.WebApi.retrieveRecord
Xrm.WebApi