Compartilhar via


Resultados de página usando FetchXML

Você pode limitar o número de linhas recuperadas para cada solicitação definindo um tamanho de página. Usando a paginação, você pode recuperar páginas consecutivas de dados para obter com eficiência todos os registros que correspondem aos critérios de uma consulta.

O tamanho de página padrão e máximo é de 5.000 para tabelas padrão e 500 para tabelas elásticas. Se você não definir um tamanho de página, o Dataverse retornará 5.000 ou 500 linhas de dados por vez, dependendo do tipo de tabela. Para obter mais linhas, você deve enviar solicitações adicionais.

Observação

  • Não use o atributo fetch elementtop com paginação. Esses métodos diferentes de limitar os resultados de uma consulta não são compatíveis.
  • A ordenação desempenha um papel importante na obtenção de resultados consistentes de paginação. Descubra mais sobre ordenação e paginação.

Modelos de paginação FetchXml

FetchXml tem dois modelos de paginação: simples e cookies de paginação:

Simples

  • Usa apenas o elemento fetchcount e os atributospage
  • Adequado apenas para pequenos conjuntos de dados
  • Não é possível retornar um conjunto de dados maior que 50.000 registros
  • O desempenho reduz à medida que o número de linhas aumenta

Cookies de paginação

Paginação simples

Solicite a primeira página definindo o atributo do fetch elementpage como 1 e o atributo de count para o tamanho da página antes de enviar a solicitação:

<fetch count='3' page='1'>
  <entity name='account'>
    <attribute name='name' />
    <order attribute='name' />
    <order attribute='accountid' />
  </entity>
</fetch>

Para obter os próximos três registros, incremente o page valor e envie outra solicitação.

<fetch count='3' page='2'>
  <entity name='account'>
    <attribute name='name' />
    <order attribute='name' />
    <order attribute='accountid' />    
  </entity>
</fetch>

Usando a paginação simples, às vezes chamada de paginação herdada, o Dataverse recupera todos os resultados da consulta até a página atual. Ele seleciona o número de registros necessários para a página e ignora o restante. Esse método facilita a navegação para trás e para frente entre os dados ou saltar para uma página específica. No entanto, o número total de registros é limitado a 50.000. Além disso, consultas complexas e resultados de consulta distintos classificados arbitrariamente podem causar problemas de desempenho.

A paginação simples funciona bem para pequenos conjuntos de dados. Mas à medida que o número de linhas no conjunto de dados aumenta, o desempenho sofre. O número total de linhas que você pode recuperar usando a paginação simples é 50.000. Para obter o melhor desempenho em todos os casos, use cookies de paginação consistentemente.

Cookies de paginação

Quando há mais linhas a serem recuperadas depois de solicitar a primeira página, o Dataverse geralmente retorna um cookie de paginação a ser usado nas solicitações a seguir para as próximas páginas.

O cookie de paginação contém dados sobre o primeiro e o último registro nos resultados. Ele ajuda o Dataverse a recuperar a próxima linha de dados o mais rápido possível. Use o cookie de paginação quando ele estiver disponível. Não modifique os dados no cookie de paginação. Defina o valor para o atributo fetch elementopaging-cookie e incremente o valor do atributo page para solicitações subsequentes.

Consultas que não dão suporte a cookies de paginação

Algumas consultas não dão suporte a cookies de paginação. Quando uma consulta não dá suporte a cookies de paginação, a consulta não retorna um valor de cookie de paginação com o resultado. Por exemplo, consultas classificadas usando um link-entity atributo podem não dar suporte a cookies de paginação.

Quando o Dataverse não retorna um cookie de paginação, o modelo de paginação volta à paginação simples, com todas as limitações que vêm com ele.

Como você usa cookies de paginação depende se você está usando o SDK para .NET ou API Web.

O método estático a seguir RetrieveAll retorna todos os registros que correspondem à consulta FetchXML. Ele envia várias solicitações se o número de registros exceder o tamanho da página.

Após cada solicitação, o método verifica a propriedade EntityCollection.MoreRecords para ver se mais registros correspondem aos critérios. Se houver mais registros, o método definirá o valor da propriedade EntityCollection.PagingCookie retornada para o paging-cookie atributo do elemento fetch e enviará outra solicitação.

/// <summary>
/// Returns all records matching the criteria
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="fetchXml">The fetchXml Query string</param>
/// <param name="pageSize">The page size to use. Default is 5,000</param>
/// <returns>All the records that match the criteria</returns>
static EntityCollection RetrieveAll(IOrganizationService service, string fetchXml, int pageSize = 5000)
{

    // The records to return
    List<Entity> entities = new();

    XElement fetchNode = XElement.Parse(fetchXml);

    int page = 1; //Start with page 1

    //Set the page
    fetchNode.SetAttributeValue("page", page);

    // Set the page size
    fetchNode.SetAttributeValue("count", pageSize);

    while (true)
    {
        // Get the page
        EntityCollection results = service.RetrieveMultiple(new FetchExpression(fetchNode.ToString()));

        entities.AddRange(results.Entities);

        if (!results.MoreRecords)
        {
            break;
        }

        // Set the fetch paging-cookie attribute with the paging cookie from the previous query
        fetchNode.SetAttributeValue("paging-cookie", results.PagingCookie);

        fetchNode.SetAttributeValue("page", ++page);
    }
    return new EntityCollection(entities);
}

Para testar consultas FetchXML, adapte o exemplo em Início Rápido: Execute um SDK para solicitação .NET (C#) usando as seguintes etapas:

  1. Adicione o RetrieveAll método estático à Program classe.
  2. Modifique o Main método conforme mostrado no código a seguir:
static void Main(string[] args)
{
    using (ServiceClient serviceClient = new(connectionString))
    {
        if (serviceClient.IsReady)
        {
            //WhoAmIResponse response = 
            //    (WhoAmIResponse)serviceClient.Execute(new WhoAmIRequest());

            //Console.WriteLine("User ID is {0}.", response.UserId);

            string fetchQuery = @"<fetch count='3' page='1'>
                <entity name='contact'>
                    <attribute name='fullname'/>
                    <attribute name='jobtitle'/>
                    <attribute name='annualincome'/>
                    <order descending='true' attribute='fullname'/>
                </entity>
        </fetch>";

            EntityCollection records = RetrieveAll(service: serviceClient,
                        fetchXml: fetchQuery,
                        pageSize: 25);

            Console.WriteLine($"Success: {records.Entities.Count}");
        }
        else
        {
            Console.WriteLine(
                "A web service connection was not established.");
        }
    }

    // Pause the console so it does not close.
    Console.WriteLine("Press the <Enter> key to exit.");
    Console.ReadLine();
}

Observação

Essa consulta retorna todos os registros que correspondem aos critérios. Inclua elementos de filtro para limitar os resultados.

Leia as informações importantes a seguir sobre como usar uma cadeia de conexão no código do aplicativo.

Importante

A Microsoft recomenda usar o fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste artigo requer um alto grau de confiança no aplicativo e traz riscos que não estão presentes em outros fluxos. Você só deve usar esse fluxo quando outros fluxos mais seguros, como identidades gerenciadas, não forem viáveis.

Ordenação e paginação

Como uma página é ordenada faz uma grande diferença ao paginar dados. Se as informações sobre como os resultados são ordenados forem ambíguas, o Dataverse não poderá retornar dados paginados de forma consistente ou eficiente.

Especifique um pedido para sua consulta. Com FetchXml, se você não adicionar elementos de ordem à consulta, o Dataverse adicionará uma ordem com base na chave primária da tabela. No entanto, QueryExpression não faz isso, e, quando sua consulta especifica distinct resultados, nenhum valor de chave primária é retornado. Assim, o Dataverse não pode adicionar essa ordem padrão. Você deve especificar uma ordem de paginação. Sem qualquer ordem especificada, distinct os resultados da consulta podem ser retornados em ordem aleatória. O OData não fornece nenhuma opção para retornar resultados distintos, mas você ainda deve aplicar uma ordem ao recuperar resultados paginados.

A paginação é dinâmica. Cada solicitação é avaliada independentemente à medida que é recebida. Um cookie de paginação indica ao Dataverse a página anterior. Com esses dados de cookie de paginação, o Dataverse pode começar com o próximo registro após o último na página anterior.

A paginação funciona melhor daqui para frente. Se você voltar e recuperar uma página recuperada anteriormente, os resultados poderão ser diferentes porque os registros podem ser adicionados, excluídos ou modificados durante a última recuperação da página. Em outras palavras, se o tamanho da página for 50 e você voltar, você obterá 50 registros, mas eles podem não ser os mesmos 50 registros. Se você continuar avançando pelas páginas de um conjunto de dados, poderá esperar que todos os registros sejam retornados em uma sequência consistente.

A ordenação determinística é importante

A ordenação determinística significa que há uma maneira de calcular uma ordem consistentemente. Com um determinado conjunto de registros, os registros são sempre retornados na mesma ordem. Se você precisar de ordens e paginação consistentes, deve incluir alguns valores exclusivos ou uma combinação de valores de coluna e especificar uma ordem para que eles sejam avaliados.

Exemplo não determinístico

Vamos examinar um exemplo que não é determinístico. Esse conjunto de dados contém apenas informações de estado e status e é filtrado para retornar apenas registros em um Estado aberto. Os resultados são ordenados pelo Status. As três primeiras páginas são solicitadas. Os resultados serão semelhantes a estes:

State Situação Página
Abrir Ativo 1 Iniciar
Abrir Ativo 1
Abrir Ativo 1 Fim
Abrir Ativo
Abrir Ativo
Abrir Inativo
Abrir Inativo

O cookie de paginação salva informações sobre o último registro na página. Quando a próxima página é solicitada, o último registro da primeira página não é incluído. No entanto, considerando os dados não determinísticos, não há garantia de que os outros dois registros na primeira página não estejam incluídos na segunda página.

Para obter a ordenação determinística, adicione ordens em colunas que contenham valores únicos ou valores semi-únicos.

Exemplo determinístico

Essa consulta é como a não determinística, mas inclui a coluna ID de Caso que inclui valores exclusivos. Ele também é ordenado pelo Status, mas também ordenado pelo ID do caso. Os resultados serão semelhantes a estes:

State Situação ID do caso Página
Abrir Ativo Case-0010 1 Iniciar
Abrir Ativo Caso-0021 1
Abrir Ativo Case-0032 1 Fim
Abrir Ativo Caso 0034
Abrir Ativo Case-0070
Abrir Inativo Case-0015
Abrir Inativo Case-0047

Na próxima página, o cookie terá Case-0032 armazenado como o último registro da primeira página, portanto, a página dois começará com o próximo após esse registro. Os resultados serão semelhantes a estes:

State Situação ID do caso Página
Abrir Ativo Case-0010 1 Iniciar
Abrir Ativo Caso-0021 1
Abrir Ativo Case-0032 1 Fim
Abrir Ativo Caso 0034 2 Iniciar
Abrir Ativo Case-0070 2
Abrir Inativo Case-0015 2 Fim
Abrir Inativo Case-0047

Como essa consulta ordena valores de coluna exclusivos, a ordem é consistente.

Práticas recomendadas para ordenações ao paginar dados

Observação

Quando possível, as consultas devem ser ordenadas na chave primária da tabela porque o Dataverse é otimizado para ordenação na chave primária por padrão. A ordenação por campos não exclusivos ou complexos causa sobrecarga em excesso e consultas mais lentas.

Ao recuperar um conjunto limitado de dados a serem exibidos em um aplicativo ou se precisar retornar mais de 5.000 linhas de dados (500 para tabelas elásticas), você precisará páginar os resultados. As escolhas que você faz para determinar a ordem dos resultados podem determinar se as linhas em cada página de dados que você recupera se sobrepõem a outras páginas. Sem a ordenação adequada, o mesmo registro pode aparecer em mais de uma página.

Para impedir que o mesmo registro apareça em mais de uma página, aplique as seguintes práticas recomendadas:

É melhor incluir uma coluna que tenha um identificador exclusivo. Por exemplo:

  • Colunas de chave primária da tabela
  • Colunas de numeração automática
  • IDs de usuário/contato

Se você não puder incluir uma coluna com um identificador exclusivo, inclua vários campos que provavelmente resultarão em combinações exclusivas. Por exemplo:

  • Nome + sobrenome + endereço de email
  • Nome completo + endereço de email
  • Endereço de email + nome da empresa

Antipadrões para ordenação ao paginar dados

A seguir, opções de ordenação a serem evitadas:

  • Pedidos que não incluem identificadores exclusivos

  • Ordens em campos calculados

  • Pedidos que têm campos únicos ou múltiplos que provavelmente não fornecerão exclusividade, como:

    • Status e estado
    • Opções ou Sim/Não
    • Nomeie valores individualmente. Por exemploname, firstnamelastname
    • Campos de texto como títulos, descrições e texto de várias linhas
    • Campos numéricos não exclusivos

Próximas Etapas 

Saiba como agregar dados.