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.
Você pode reduzir a complexidade dos cenários de integração de dados usando a Upsert mensagem. Ao carregar dados no Microsoft Dataverse de um sistema externo, como em um cenário de integração de dados em massa, talvez você não saiba se já existe um registro no Dataverse. Nesses casos, você não consegue decidir se deve usar a mensagem Update ou a mensagem Create. Primeiro você deve recuperar o registro para verificar se ele existe antes de executar a operação apropriada. Você pode reduzir essa complexidade e carregar dados no Dataverse com mais eficiência usando a Upsert mensagem.
Há uma penalidade de desempenho quando você usa Upsert em vez de Create. Se você tiver certeza de que o registro não existe, use Create.
Observação
Embora você possa usar valores de chave primária com Upsert, geralmente é esperado que você use chaves alternativas porque o caso de uso comum são cenários de integração de dados. Para obter mais informações, consulte Usar uma chave alternativa para fazer referência a um registro.
Inserção/atualização de tabela elástica
O comportamento da Upsert tabela elástica difere das tabelas padrão. Usando tabelas elásticas, a operação Upsert não chama a mensagem Create ou a mensagem Update dependendo se o registro já existe.
Upsert aplica diretamente as alterações na entidade.
-
Se o registro existir: a operação substituirá todos os dados no registro com os dados na entidade. Não há evento
Update. -
Se o registro não existir: a operação criará um novo registro. Não há evento
Create.
Esse comportamento afeta o local em que você aplica a lógica de negócios a eventos. Você pode criar um novo registro usando ou Create ou Upsert. Você pode atualizar um registro usando ou Update ou Upsert. Se você precisar aplicar a lógica consistentemente para Create ou Update em tabelas elásticas, também deverá incluir essa lógica em Upsert. Para obter mais informações, consulte Inserir ou atualizar um registro em uma tabela elástica.
Entender o processo upsert para tabelas padrão
O servidor processa upsert mensagens. O SDK para classes .NET usa os mesmos objetos que o servidor. Portanto, a explicação a seguir usa o SDK para classes .NET para descrever como o servidor processa uma instância de classe UpsertRequest e retorna uma instância de classe UpsertResponse .
As etapas a seguir descrevem a lógica de processamento no servidor quando ele recebe um UpsertRequest para uma tabela padrão:
- A instância UpsertRequest chega com a propriedade Target definida para uma instância de Entidade que contém os dados de uma
CreateouUpdateoperação.- A instância de entidade normalmente tem a propriedade Entity.KeyAttributes definida com valores que identificam o registro usando chaves alternativas.
- Se existir, o Dataverse tentará pesquisar o registro usando a propriedade Entity.Id da instância de Entidade atribuída à propriedade Target. Caso contrário, ele usará os valores de chave alternativos da propriedade Entity.KeyAttributes.
- Se o registro existir:
- Defina o
TargetEntity.Id como o valor da chave primária do registro encontrado. - Remova todos os
Targetdados da coleção Entity.Attributes que usa as mesmas chaves daTargetcoleção Entity.KeyAttributes. - Chamar
Update. - Defina a propriedade UpsertResponse.RecordCreated como
false. - Crie um EntityReference utilizando a
Targetentidade como valor para UpsertResponse.Target. - Retorne o UpsertResponse.
- Defina o
-
Se o registro não existir:
- Copie qualquer dado do
TargetEntity.KeyAttributes que ainda não esteja presente em sua coleção Entity.Attributes para oTargetEntity.Attributes. - Chamar
Create. - Configure o UpsertResponse.RecordCreated como
true. - Crie uma EntityReference da
Targetentidade e oidresultado daCreateoperação como o valor de UpsertResponse.Target. - Retorne o UpsertResponse.
- Copie qualquer dado do
O diagrama a seguir mostra o processo no servidor quando ele recebe um UpsertRequest.
Diretrizes para compor solicitações
Quando você usa chaves alternativas para identificar um registro, não inclua os dados de chave alternativos na parte da solicitação que representa os dados a serem salvos.
Se você estiver usando a API Web e não estiver familiarizado com o SDK para .NET, o processo do lado do servidor descrito anteriormente pode ser difícil de seguir. A API Web não tem o mesmo modelo de objeto que os objetos SDK usados na descrição e no diagrama anteriormente, mas você pode mapear os dados, conforme mostrado na tabela a seguir.
| Web API | SDK | Descrição |
|---|---|---|
| Valores de chave na URL | Propriedade Entity.KeyAttributes | Contém os dados de chave alternativos para identificar o registro. |
| Corpo da solicitação | A entidade definida para a propriedade UpsertRequest.Target | Contém os dados a serem usados para Create ou Update. |
Embora o servidor processe essas solicitações conforme descrito anteriormente, você pode pensar dessa forma:
- Se o registro existir: O servidor remove o conjunto de dados no corpo da solicitação para esses valores de chave alternativos na URL, portanto, não há nenhum ponto em incluí-lo. Essa prática garante que você não possa atualizar os valores de chave alternativos de um registro quando estiver usando esses valores de chave alternativos para identificá-lo. Você pode alterar valores de chave alternativos usando a chave primária ou um conjunto diferente de chaves alternativas.
- Se o registro não existir: O servidor usa quaisquer valores de chave alternativos definidos no corpo da solicitação para criar o novo registro, mesmo que os dados sejam diferentes dos valores especificados pelas chaves alternativas na URL. Se não houver dados de chave alternativos no corpo da solicitação, o servidor copiará os dados de chave alternativos da URL para o corpo da solicitação. Para evitar uma situação em que os valores de chave na URL e os valores de chave correspondentes no corpo não correspondam, não os inclua no corpo.
Usar API Web
Usando a API Web, você pode iniciar as mensagens Upsert e Update enviando uma solicitação HTTP PATCH para o recurso especificado EntitySet. As chaves na URL identificam o recurso.
A diferença entre Upsert e Update depende se você inclui o cabeçalho da solicitação If-Match: * . Se você incluir o cabeçalho da If-Match: * solicitação e nenhum recurso corresponder ao valor da chave na URL, a solicitação retornará um código de status 404 Not Found. O If-Match: * cabeçalho da solicitação garante que a PATCH solicitação seja uma Update operação.
Se você não incluir o cabeçalho da If-Match: * solicitação, a solicitação PATCH será tratada como um Upsert. A solicitação criará um novo registro se não encontrar nenhum registro que corresponda às chaves na URL. No entanto, ao contrário do SDK, a resposta não informa se ele criou um registro. A resposta de status está 204 No Content em ambos os casos.
Se você incluir um Prefer: return=representation cabeçalho de solicitação, o sistema retornará um status 201 Created para Create e um status 200 OK para Update. Adicionar esse cabeçalho adiciona uma operação extra Retrieve , portanto, afeta o desempenho. Se você usar essa opção, verifique se a opção $select de consulta adicionada inclui apenas o valor da chave primária. Para obter mais informações, consulte:
Usando uma solicitação PATCH, você também pode incluir o cabeçalho de solicitação If-None-Match: * para bloquear Update caso você queira apenas criar registros. Para obter mais informações, consulte Limites para operações de upsert.
Código de exemplo da API Web
Os exemplos a seguir mostram Upsert operações usando uma tabela com duas colunas de chave alternativas:
Criar com upsert
Essa solicitação cria um registro.
Solicitação:
PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2) HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: application/json
{ "example_name": "2:2" }
Resposta:
HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2)
Atualizar com upsert
Essa solicitação atualiza o registro criado pela solicitação anterior.
Solicitação:
PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2) HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: application/json
{ "example_name": "2:2 Updated" }
Resposta:
HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2)
Observação
A resposta é idêntica para operações Create ou Update.
Criar com upsert e preferência return=representation
Ao usar o Prefer: return=representation cabeçalho, você pode obter um código de status diferente na resposta para indicar se o registro foi criado ou atualizado.
A solicitação a seguir cria um novo registro e retorna o status 201 Created.
Solicitação:
PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=3,example_key2=3)?$select=example_recordid HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Prefer: return=representation
Content-Type: application/json
{ "example_name": "3:3" }
Resposta:
HTTP/1.1 201 Created
Content-Type: application/json; odata.metadata=minimal
ETag: W/"71004878"
Preference-Applied: return=representation
OData-Version: 4.0
{
"@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#example_records(example_recordid)/$entity",
"@odata.etag": "W/\"71004878\"",
"example_recordid": "ef0d112e-d70e-ed11-82e5-00224822577b"
}
Atualizar com a preferência Upsert e return=representation
Essa solicitação atualiza o registro criado pela solicitação anterior e retorna o status 200 OK para mostrar que se trata de uma operação de atualização.
Solicitação:
PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=3,example_key2=3)?$select=example_recordid HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Prefer: return=representation
Content-Type: application/json
{ "example_name": "3:3 Updated" }
Resposta:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
ETag: W/"71004880"
OData-Version: 4.0
{
"@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#example_records(example_recordid)/$entity",
"@odata.etag": "W/\"71004880\"",
"example_recordid": "ef0d112e-d70e-ed11-82e5-00224822577b"
}
Usar o SDK para .NET
Seu aplicativo cliente usa o método IOrganizationService.Execute com uma instância UpsertRequest que tem a propriedade Target definida com uma instância de entidade que contém os dados de uma Create ou Update operação. Normalmente, você define a propriedade Entity.KeyAttributes na instância de entidade com valores usados para identificar o registro usando chaves alternativas.
A propriedade UpsertResponse.RecordCreated informa se o registro foi criado e o UpsertResponse.Target contém uma referência ao registro que foi criado ou atualizado.
Código de exemplo do SDK para .NET
O arquivo SampleMethod.cs no exemplo Inserção de registro usando Upsert contém o seguinte método ProcessUpsert. Esse método aplica a UpsertRequest mensagem no conteúdo de um arquivo XML para criar novos registros ou atualizar os existentes.
public static void ProcessUpsert(CrmServiceClient service, String Filename)
{
Console.WriteLine("Executing upsert operation.....");
XmlTextReader tr = new XmlTextReader(Filename);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(tr);
XmlNodeList xnlNodes = xdoc.DocumentElement.SelectNodes("/products/product");
foreach (XmlNode xndNode in xnlNodes)
{
String productCode = xndNode.SelectSingleNode("Code").InnerText;
String productName = xndNode.SelectSingleNode("Name").InnerText;
String productCategory = xndNode.SelectSingleNode("Category").InnerText;
String productMake = xndNode.SelectSingleNode("Make").InnerText;
//use alternate key for product
Entity productToCreate = new Entity("sample_product", "sample_productcode", productCode);
productToCreate["sample_name"] = productName;
productToCreate["sample_category"] = productCategory;
productToCreate["sample_make"] = productMake;
var request = new UpsertRequest()
{
Target = productToCreate
};
try
{
// Execute UpsertRequest and obtain UpsertResponse.
var response = (UpsertResponse)service.Execute(request);
if (response.RecordCreated)
Console.WriteLine("New record {0} is created!", productName);
else
Console.WriteLine("Existing record {0} is updated!", productName);
}
// Catch any service fault exceptions that Dataverse throws.
catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)
{
throw;
}
}
}
Consulte também
Use o controle de alterações para sincronizar dados com sistemas externos
Definir chaves alternativas para uma tabela
Usar uma chave alternativa para fazer referência a um registro