Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Para obter o melhor desempenho ao executar operações em várias linhas de uma tabela do Microsoft Dataverse, use uma das seguintes mensagens de operação em massa:
-
CreateMultiple: cria vários registros do mesmo tipo em uma única solicitação. -
UpdateMultiple: atualiza vários registros do mesmo tipo em uma única solicitação. -
UpsertMultiple: cria ou atualiza vários registros do mesmo tipo em uma única solicitação. -
DeleteMultiple: somente para tabelas elásticas. Exclui vários registros do mesmo tipo em uma única solicitação.
Observação
Para obter diretrizes sobre opções ao executar operações em massa, como quando usar essas APIs em comparação com APIs em lote, consulte ExecuteMultipleOtimizar o desempenho para operações em massa.
Exemplos
Os exemplos de código a seguir mostram como usar mensagens de operação em massa. Você pode baixar os exemplos de github.com/microsoft/PowerApps-Samples:
- Exemplo: SDK para .NET Uso de operações em lote
- Exemplo: API Web usa operações em massa
- Código de exemplo de tabela elástica
CreateMultiple
Cria vários registros do mesmo tipo em uma única solicitação.
Usa a classe CreateMultipleRequest.
/// <summary>
/// Demonstrates the use of the CreateMultiple Message
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="recordsToCreate">A list of records of the same table to create.</param>
/// <returns>The Guid values of the records created.</returns>
static Guid[] CreateMultipleExample(IOrganizationService service,
List<Entity> recordsToCreate)
{
// Create an EntityCollection populated with the list of entities.
EntityCollection entities = new(recordsToCreate)
{
// All the records must be for the same table.
EntityName = recordsToCreate[0].LogicalName
};
// Instantiate CreateMultipleRequest
CreateMultipleRequest createMultipleRequest = new()
{
Targets = entities,
};
// Send the request
CreateMultipleResponse createMultipleResponse =
(CreateMultipleResponse)service.Execute(createMultipleRequest);
// Return the Ids of the records created.
return createMultipleResponse.Ids;
}
UpdateMultiple
Atualiza vários registros do mesmo tipo em uma única solicitação.
Assim como quando você atualiza registros individuais, os dados que você envia usando UpdateMultiple devem conter apenas os valores que você está alterando. Para obter mais informações, consulte atualizar registros com o SDK para .NET e atualizar registros com a API Web.
Usa a classe UpdateMultipleRequest.
/// <summary>
/// Demonstrates the use of the UpdateMultiple message.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="recordsToUpdate">A list of records to create.</param>
static void UpdateMultipleExample(IOrganizationService service, List<Entity> recordsToUpdate) {
// Create an EntityCollection populated with the list of entities.
EntityCollection entities = new(recordsToUpdate)
{
// All the records must be for the same table.
EntityName = recordsToUpdate[0].LogicalName
};
// Use UpdateMultipleRequest
UpdateMultipleRequest updateMultipleRequest = new()
{
Targets = entities,
};
service.Execute(updateMultipleRequest);
}
Registros duplicados no parâmetro UpdateMultiple Targets
UpdateMultiple não dá suporte a vários registros com a mesma chave primária ou valores de chave alternativos na carga. Quando mais de um registro no Targets parâmetro é identificado exclusivamente por uma chave primária ou alternativa, a operação é executada somente no primeiro registro. A operação ignora quaisquer registros subsequentes que tenham os mesmos valores de chave na carga útil.
Esse comportamento é diferente de UpsertMultiple.
UpsertMultiple
Use Upsert para integrar dados a fontes externas quando você não souber se a tabela existe no Dataverse.
Upsert as operações geralmente dependem de chaves alternativas para identificar registros. Use UpsertMultiple para realizar Upsert operações em massa.
Usa a classe UpsertMultipleRequest.
Esse método estático UpsertMultipleExample depende de uma samples_bankaccount tabela que tenha uma coluna de cadeia de caracteres chamada samples_accountname configurada como uma chave alternativa. Ele também tem uma coluna de cadeia de caracteres chamada samples_description. Esse código usa o construtor Entity que define o keyName e keyValue para especificar o valor de chave alternativo.
/// <summary>
/// Demonstrates using UpsertMultiple with alternate key values
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
static void UpsertMultipleExample(IOrganizationService service)
{
var tableLogicalName = "samples_bankaccount";
// samples_accountname string column is configued as an alternate key
// for the samples_bankaccount table
var altKeyColumnLogicalName = "samples_accountname";
// Create one record to update with upsert
service.Create(new Entity(tableLogicalName)
{
Attributes =
{
{altKeyColumnLogicalName, "Record For Update"},
{"samples_description","A record to update using Upsert" }
}
});
// Using the Entity constructor to specify alternate key
Entity toUpdate = new(
entityName: tableLogicalName,
keyName: altKeyColumnLogicalName,
// Same alternate key value as created record.
keyValue: "Record For Update");
toUpdate["samples_description"] = "Updated using Upsert";
Entity toCreate = new(
entityName: tableLogicalName,
keyName: altKeyColumnLogicalName,
keyValue: "Record For Create");
toCreate["samples_description"] = "A record to create using Upsert";
// Add the records to a collection
EntityCollection records = new()
{
EntityName = tableLogicalName,
Entities = { toUpdate, toCreate }
};
// Send the request
UpsertMultipleRequest request = new()
{
Targets = records
};
var response = (UpsertMultipleResponse)service.Execute(request);
// Process the responses:
foreach (UpsertResponse item in response.Results)
{
Console.WriteLine($"Record {(item.RecordCreated ? "Created" : "Updated")}");
}
}
Saída:
Record Updated
Record Created
Se um registro é criado ou atualizado neste exemplo depende se os registros existem com o valor correspondente sample_keyattribute . Nenhum dado é retornado para indicar se um registro foi criado ou atualizado.
Exemplos SDK
Em Exemplo: SDK para .NET e uso de operações em massa, procure o projeto UpsertMultiple.
Disponibilidade
UpsertMultiple está disponível para tabelas compatíveis com CreateMultiple e UpdateMultiple. Esse suporte inclui todas as tabelas elásticas. As consultas encontradas em Disponibilidade com tabelas padrão não retornam resultados para UpsertMultiple, mas você pode usá-las para detectar se uma tabela suporta tanto CreateMultiple quanto UpdateMultiple.
Essas consultas não retornam resultados para a UpsertMultiple mensagem. Uma tabela que dá suporte tanto a CreateMultiple quanto a UpdateMultiple dá suporte a UpsertMultiple.
Registros duplicados no parâmetro UpsertMultiple Targets
UpsertMultiple não dá suporte a vários registros com a mesma chave primária ou valores de chave alternativos na carga. Quando mais de um registro no Targets parâmetro é identificado exclusivamente por uma chave primária ou alternativa, UpsertMultiple retorna um erro.
Esse comportamento é diferente de UpdateMultiple.
ExcluirMúltiplos
Exclua várias linhas de dados em tabelas elásticas com uma única solicitação.
Use a classe OrganizationRequest porque o SDK para .NET não tem DeleteMultipleRequest classe. Para obter mais informações, consulte usar mensagens com o SDK para .NET.
DeleteMultipleExample O método estático a seguir usa a DeleteMultiple mensagem com a classe OrganizationRequest para excluir várias linhas da contoso_SensorData tabela elástica usando a chave alternativa para incluir a partitionid para identificar exclusivamente as linhas.
public static void DeleteMultipleExample(IOrganizationService service)
{
string tableLogicalName = "contoso_sensordata";
List<EntityReference> entityReferences = new() {
{
new EntityReference(logicalName: tableLogicalName,
keyAttributeCollection: new KeyAttributeCollection
{
{ "contoso_sensordataid", "3f56361a-b210-4a74-8708-3c664038fa41" },
{ "partitionid", "deviceid-001" }
})
},
{ new EntityReference(logicalName: tableLogicalName,
keyAttributeCollection: new KeyAttributeCollection
{
{ "contoso_sensordataid", "e682715b-1bba-415e-b2bc-de9327308423" },
{ "partitionid", "deviceid-002" }
})
}
};
OrganizationRequest request = new(requestName:"DeleteMultiple")
{
Parameters = {
{"Targets", new EntityReferenceCollection(entityReferences)}
}
};
service.Execute(request);
}
Disponibilidade de DeleteMultiple
DeleteMultiple tem suporte apenas para tabelas elásticas. As tabelas elásticas não dão suporte ao comportamento em cascata da relação de tabela, o que pode resultar em tempos de execução imprevisíveis para operações de exclusão. Se você usar DeleteMultiple em uma tabela padrão, receberá o erro: DeleteMultiple has not yet been implemented.
Excluir Múltiplos Exemplos
Você pode encontrar um código de exemplo no GitHub no github.com/microsoft/PowerApps-Samples:
- Código de exemplo de tabela elástica
- Em Exemplo: SDK para .NET usando operações em massa ou Exemplo: API Web usando operações em massa, altere o
Settings.csarquivo de configuração e selecione a opçãoUseElastic.
Uso de tabelas padrão e elásticas
As tabelas standard e as tabelas elásticas recebem um aumento de desempenho significativo quando você usa mensagens de operação em massa, mas é necessário usá-las de maneiras diferentes. A tabela a seguir resume as diferenças.
| Diferença | Standard | Elastic |
|---|---|---|
| Número de registros | As operações são mais eficientes com um número maior de registros. Não há limite para o número de registros, mas há limites de tempo e tamanho da mensagem. Envie de 100 a 1.000 registros por vez. | Envie 100 registros por vez. |
| Sobre o comportamento de erro | Todas as operações são revertidas em caso de erro. | O sucesso parcial é possível. |
| Disponibilidade | Nem todas as tabelas padrão dão suporte a essas mensagens. | As mensagens estão disponíveis para todas as tabelas elásticas. |
| DeletarMúltiplos | Não disponível. Use a classe BulkDeleteRequest do SDK ou a ação BulkDelete da API Web. Saiba como excluir dados em massa. | Usar a classe DeleteMultipleRequest do SDK ou a ação DeleteMultiple da API Web |
O uso de tabelas padrão e elástica é diferente porque as tabelas padrão usam o SQL do Azure e dão suporte a transações. As tabelas elásticas usam o Azure Cosmos DB, que não dá suporte a transações, mas lida com grandes quantidades de dados em altos níveis de taxa de transferência com baixa latência. As seções a seguir fornecem mais detalhes. Saiba mais sobre operações em massa em tabelas elásticas.
Número de registros
O número de registros que você deve incluir com cada solicitação depende se você está usando tabelas padrão ou elásticas.
Dica
As tabelas standard e elástica têm maior taxa de transferência quando você envia mensagens de operação em massa em paralelo.
Número de registros com tabelas padrão
As operações em massa em tabelas padrão são otimizadas para serem executadas em várias linhas em uma única transação. As operações se tornam mais eficientes e o desempenho aumenta no geral, à medida que o número de operações por solicitação aumenta. Essa otimização também torna as etapas de plug-in registradas para a operação em lote mais eficientes. Sempre que um plug-in é invocado para uma única operação, o processo requer alguns milissegundos para invocar a classe plug-in que contém a lógica. Quando você registra um plug-in para uma mensagem de operação em massa, a classe é invocada uma vez e pode processar todas as operações com mais eficiência. Saiba como escrever plug-ins para CreateMultiple e UpdateMultiple.
Esse benefício de desempenho incentiva você a enviar o maior número de registros que puder em cada solicitação. No entanto, à medida que o número de registros aumenta, o tamanho da solicitação também aumenta e a solicitação leva mais tempo para ser processada. Eventualmente, você encontra o tamanho da mensagem e os limites de tempo. Se você atingir esses limites, toda a operação falhará. Não há um limite definido no número de registros que você pode enviar. Talvez seja necessário experimentar para encontrar o melhor número. Geralmente, de 100 a 1.000 registros por solicitação é um lugar razoável para começar se o tamanho dos dados de registro for pequeno e não houver plug-ins. Os tipos de erros que você pode encontrar geralmente podem ser resolvidos enviando menos registros com cada solicitação. Inclua a capacidade de configurar o número de entidades enviadas para que você possa se adaptar enviando menos.
Número de registros com tabelas elásticas
Como não há nenhuma transação com tabelas elásticas, não há nenhum benefício de desempenho na tentativa de enviar um grande número de registros por solicitação. Envie 100 operações por solicitação e envie solicitações em paralelo para atingir a taxa de transferência máxima.
Sobre o comportamento do erro
O comportamento quando ocorrem erros depende se você está usando tabelas padrão ou tabelas elásticas.
Sobre o comportamento de erro com tabelas padrão
Qualquer erro que ocorra em uma operação em lote com uma tabela padrão faz com que toda a operação seja anulada. Use apenas operações em massa em tabelas padrão quando tiver um alto grau de confiança de que todas as operações serão bem-sucedidas. Para permitir que o conjunto de operações seja revertido se a operação em massa falhar, considere usar a classe ExecuteMultipleRequest do SDK ou a $batchAPI Web. Se a taxa de sucesso de suas tentativas iniciais for baixa, essa estratégia resultará em um desempenho pior. Use apenas essa estratégia de fallback quando você espera que a maioria das operações tenha êxito.
Sobre o comportamento em caso de erro com tabelas elásticas
Com tabelas elásticas, uma operação em massa pode ser parcialmente bem-sucedida. Você pode usar os detalhes do erro para identificar quais registros falharam.
Quando você usa o SDK para executar uma operação em massa em uma tabela elástica, uma FaultException do tipo OrganizationServiceFault é gerada se ocorrer uma falha. Use o código a seguir para obter o status de cada registro.
if (ex.Detail.ErrorDetails.TryGetValue("Plugin.BulkApiErrorDetails", out object errorDetails))
{
List<BulkApiErrorDetail> bulkApiErrorDetails = JsonConvert.DeserializeObject<List<BulkApiErrorDetail>>(errorDetails.ToString());
}
public class BulkApiErrorDetail
{
public int RequestIndex { get; set; }
public string Id { get; set; }
public int StatusCode { get; set; }
}
Disponibilidade
A disponibilidade de mensagens de operações em massa depende se você está usando tabelas padrão ou tabelas elásticas. Todas as tabelas elásticas dão suporte às mensagens CreateMultiple, UpdateMultiple, UpsertMultiple e DeleteMultiple.
Disponibilidade com tabelas padrão
Você pode usar as CreateMultiple mensagens de operação em massa UpdateMultiple com tabelas padrão personalizadas e muitas tabelas padrão comuns, mas não todas. Teste se as tabelas padrão individuais dão suporte a essas mensagens. Os exemplos a seguir mostram como fazer isso.
Use este método estático para detectar se uma determinada tabela suporta CreateMultiple ou UpdateMultiple.
/// <summary>
/// Detect whether a specified message is supported for the specified table.
/// </summary>
/// <param name="service">The IOrganizationService instance.</param>
/// <param name="entityLogicalName">The logical name of the table.</param>
/// <param name="messageName">The name of the message.</param>
/// <returns></returns>
public static bool IsMessageAvailable(
IOrganizationService service,
string entityLogicalName,
string messageName)
{
QueryExpression query = new("sdkmessagefilter")
{
ColumnSet = new ColumnSet("sdkmessagefilterid"),
Criteria = new FilterExpression(LogicalOperator.And)
{
Conditions = {
new ConditionExpression(
attributeName:"primaryobjecttypecode",
conditionOperator: ConditionOperator.Equal,
value: entityLogicalName)
}
},
LinkEntities = {
new LinkEntity(
linkFromEntityName:"sdkmessagefilter",
linkToEntityName:"sdkmessage",
linkFromAttributeName:"sdkmessageid",
linkToAttributeName:"sdkmessageid",
joinOperator: JoinOperator.Inner)
{
LinkCriteria = new FilterExpression(LogicalOperator.And){
Conditions = {
new ConditionExpression(
attributeName:"name",
conditionOperator: ConditionOperator.Equal,
value: messageName)
}
}
}
}
};
EntityCollection entityCollection = service.RetrieveMultiple(query);
return entityCollection.Entities.Count.Equals(1);
}
Encaminhamentos de mensagens mesclados
Cada mensagem de operação em massa tem uma mensagem correspondente que opera em linhas individuais: Create, Updatee Delete. Essas mensagens existem há muito tempo e muitas organizações têm uma lógica personalizada que depende dos eventos que ocorrem quando essas mensagens são usadas.
Um requisito fundamental das mensagens de operação em massa é que as organizações não devem manter a lógica personalizada em dois locais. Para ter a mesma lógica personalizada e mantê-la em um só lugar, o Dataverse mescla os pipelines de processamento destas mensagens. O que significa essa mesclagem?
Quando você utiliza uma mensagem de operação em massa, os respectivos eventos
CreateeUpdateocorrem para cada instância de Entidade no parâmetroTargets. Os plug-ins ou outros manipuladores de eventos para os eventos individuais correspondentes continuam funcionando como sempre funcionaram. Você não precisa escrever novos plug-ins para gerenciar eventos gerados por essas mensagens.Quando você usa uma única mensagem de operação, o respectivo evento de operação em massa ocorre com uma EntityCollection contendo uma única instância de entidade passada no
Targetsparâmetro. Você pode mover qualquer lógica que responda a eventos de operação única para os eventos de operação em massa mais eficientes e a lógica é aplicada para operações individuais e múltiplas.
Antes da introdução de mensagens de operação em massa, toda a lógica personalizada estava nas mensagens de operação única. Essa lógica continua a ser aplicada quando os aplicativos cliente usam as mensagens de operação em massa. Para tabelas usadas com operações em massa de alto volume, mova qualquer lógica síncrona de eventos de mensagem única para eventos de operação em massa. Se você estiver introduzindo uma nova lógica, use os eventos de operação em massa em vez dos eventos de operação única.
Cuidado
Com esse design, a lógica duplicada pode potencialmente ser aplicada nas versões única e múltipla de eventos. O Dataverse não tenta impedir isso porque não pode saber sua intenção.
É sua responsabilidade garantir que a mesma lógica aplicada para a versão única dos eventos seja migrada para a versão múltipla do evento e removida da versão única do evento. Caso contrário, a lógica se aplica duas vezes.
Saiba como escrever plug-ins para CreateMultiple e UpdateMultiple.
Limitações
Tenha em mente as seguintes limitações ao usar mensagens de operação em massa.
Tamanho da mensagem e limites de tempo
Para tabelas padrão, você obtém melhor desempenho ao enviar mais registros com cada solicitação. No entanto, o tamanho da carga útil e o tempo necessário para processar a operação limitam o número de registros que você pode enviar.
Limites de tamanho de mensagem
Se você registrar um plug-in para qualquer mensagem, poderá encontrar o erro "Tamanho da mensagem excedido ao enviar contexto para o Sandbox" quando o tamanho total da solicitação exceder 116,85 MB. Ao usar mensagens de operação em massa, você pode alcançar mais facilmente esse limite porque envia cargas maiores.
Esse erro não ocorrerá se você não registrar um plug-in para o evento. Para evitar o erro, desabilite qualquer plug-in ou envie sua solicitação usando o BypassCustomPluginExecution parâmetro opcional.
Limites de tempo
Se você usar o Dataverse ServiceClient, poderá encontrar este erro:
The request channel timed out attempting to send after 00:04:00.
Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding.
The time allotted to this operation may have been a portion of a longer timeout.
O tempo limite padrão definido usando ServiceClient é de quatro minutos, o que é longo para qualquer operação síncrona. Você pode alterar esse valor usando a propriedade Static ServiceClient.MaxConnectionTimeout . O tempo limite padrão usando CrmServiceClient é de dois minutos.
Observação
Antes de aumentar os limites de tempo, considere reduzir o número de registros que você passa no Targets parâmetro.
Não há suporte para uso em plug-ins
Atualmente, o Dataverse não dá suporte ao uso de mensagens de operação em massa no código de plug-in. Para obter mais informações, consulte Não usar tipos de solicitação em lote em plug-ins e atividades de fluxo de trabalho.
No entanto, você deve escrever plug-ins para as mensagens CreateMultiple e UpdateMultiple conforme descrito em Escrever plug-ins para CreateMultiple e UpdateMultiple.
Solucionar erros comuns
Se você encontrar erros ao usar operações em massa, consulte os seguintes artigos:
- Solucionar problemas de erros de operação em massa do Dataverse
- Solucionar problemas de erros de cliente do Dataverse
Perguntas frequentes (FAQ)
Se você não encontrar uma resposta neste artigo para perguntas sobre como usar mensagens de operação em massa, use o botão na parte inferior da página para enviar e exibir comentários para esta página. Você precisa de uma conta do GitHub para enviar comentários.
A lógica Retrieve e RetrieveMultiple será mesclada?
A Microsoft não planeja alterar o comportamento da mensagem RetrieveRetrieveMultiple. Essas mensagens são mensagens separadas há muitos anos e os desenvolvedores sempre precisam manter a lógica para elas separadamente. Tentar mesclar o pipeline de mensagens para eles seria altamente problemático. Além disso, evite aplicar lógica personalizada a essas mensagens devido ao impacto que elas podem ter no desempenho.
Como os limites de API são aplicados?
Dois tipos de limites de API se aplicam. As mensagens de operação em massa não fornecem nenhuma maneira de ignorar nenhum dos tipos.
Limites de proteção de serviço
Conforme descrito nos limites da API de proteção de serviço, os limites têm três facetas. Dois desses limites são avaliados em uma janela deslizante de cinco minutos e se aplicam ao usar essas mensagens.
- Número de solicitações: cada mensagem de operação em massa conta como uma única solicitação que se acumula até o limite de 6.000 solicitações por usuário, por servidor, durante a janela de cinco minutos. Como essas solicitações agrupam operações individuais, a probabilidade de atingir esse limite é reduzida.
- Tempo de execução: como cada solicitação de mensagem de operação em massa normalmente leva mais tempo, se você estiver enviando solicitações em paralelo, é mais provável que você atinja o limite de tempo de execução de 20 minutos por usuário, por servidor, durante a janela de cinco minutos.
Limites de Solicitação do Power Platform (Limites de Concessão de API)
Esses limites são baseados em alterações de dados: Create, Update, e Delete operações. Cada item incluído no parâmetro Targets de uma solicitação de operação em massa se acumula até esse limite.
Saiba mais sobre limites de solicitação e alocações.
Consulte também
Tabelas elásticas
Escrever plug-ins para CreateMultiple e UpdateMultiple
Exemplo: SDK para .NET Uso de operações em lote
Exemplo: API Web usa operações em massa
Exemplo: plug-ins CreateMultiple e UpdateMultiple
Usar mensagens com o SDK para .NET
Otimizar o desempenho para operações em massa