Use Upsert para crear o actualizar un registro
Puede reducir la complejidad que caracteriza a los escenarios de integración de datos mediante el mensaje Upsert
. Al cargar datos en Microsoft Dataverse desde un sistema externo, por ejemplo en un escenario de integración de datos en masa, quizá no sepa si ya existe un registro en Dataverse. En tales casos, no sabrá si debe debe usar un mensaje Update
o Create
. Debe retirar el registro primero para determinar si existe antes de realizar la operación adecuada. Puede reducir esta complejidad y cargar datos en Dataverse de manera más eficiente utilizando el mensaje Upsert
.
Hay una penalización del rendimiento con Upsert
en lugar de usar Create
. Si está seguro de que el registro no existe, use Create
.
Nota
Si bien puede usar valores de clave principal con Upsert
, generalmente se espera que use claves alternativas porque el caso de uso común son los escenarios de integración de datos. Más información: Usar una clave alternativa para hacer referencia a un registro
Upsert de tabla elástica
El comportamiento de la tabla elástica para Upsert
es diferente al de las tablas estándar. Con las tablas elásticas, la operación Upsert
no llama al mensaje Create
o Update
dependiendo de si el registro ya existe o no. Upsert
aplica directamente los cambios en la entidad.
- Si el registro existe: Todos los datos del registro se sobrescriben con los datos de la entidad. No hay ningún evento de
Update
. - Si el registro no existe: se crea un nuevo registro. No hay ningún evento de
Create
.
Esto tiene implicaciones sobre dónde aplica la lógica empresarial para los eventos. Se puede crear un nuevo registro usando Create
o Upsert
. Un registro se puede actualizar usando Update
o Upsert
. Si necesita aplicar lógica consistentemente para Create
o Update
en tablas elásticas, también debe incluir esa lógica en Upsert
. Más información: Upsert un registro en una tabla elástica
Comprensión del proceso de Upsert para tablas estándar
Los mensajes Upsert
se procesan en el servidor. El SDK para las clases .NET usa los mismos objetos que se usan en el servidor. Por lo tanto, la siguiente explicación usa el SDK para clases .NET para describir cómo se procesa una instancia UpsertRequest y cómo se devuelve la instancia UpsertResponse.
Los siguientes pasos describen la lógica de procesamiento en el servidor cuando se recibe una UpsertRequest para una tabla estándar:
- La instancia UpsertRequest llega con Target Property configurada con una instancia Entity que contiene los datos de una operación
Create
oUpdate
.- La instancia Entity normalmente tendrá Entity.KeyAttributes Property configurada con valores utilizados para identificar el registro mediante claves alternativas.
- Si existe, Dataverse intentará buscar el registro usando la propiedad Entity.Id de la instancia Entity establecida en la propiedad Target. De lo contrario, usa los valores clave alternativa de Entity.KeyAttributes Property.
- Si existe el registro:
- Seleccione el
Target
Entity.Id con el valor de clave principal del registro encontrado. - Elimine todos los datos de la colección
Target
Entity.Attributes que utilicen las mismas claves utilizadas en la colecciónTarget
Entity.KeyAttributes. - Llame a
Update
. - Establezca la propiedad UpsertResponse.RecordCreated en
false
. - Cree un EntityReference de la entidad
Target
como valor para UpsertResponse.Target. - Devuelva la UpsertResponse.
- Seleccione el
- Si el registro no existe:
- Copie cualquier dato de
Target
Entity.KeyAttributes que elTarget
no tenga en su colección Entity.Attributes en elTarget
Entity.Attributes. - Llame a
Create
. - Establezca la UpsertResponse.RecordCreated como
true
. - Cree una EntityReference desde la entidad
Target
y elid
de resultado de la operaciónCreate
como valor para UpsertResponse.Target. - Devuelva la UpsertResponse.
- Copie cualquier dato de
El siguiente diagrama muestra el proceso en el servidor cuando se recibe una UpsertRequest.
Orientación para redactar solicitudes
Cuando se usan claves alternativas para identificar un registro, no se recomienda ni es necesario incluir los datos clave alternativos en la parte de la solicitud que representa los datos que se guardarán.
Si está utilizando la API web y no está familiarizado con el SDK para .NET, el proceso del lado del servidor descrito anteriormente puede ser difícil de seguir. La API web no tiene el mismo modelo de objeto que los objetos SDK que se usan en la descripción y el diagrama anterior, pero los datos se pueden asignar como se muestra en la siguiente tabla.
API Web | SDK de | Descripción |
---|---|---|
Valores de clave en URL | Entity.KeyAttributes Property | Contiene los datos de clave alternativa para identificar el registro. |
Cuerpo de la solicitud | La Entity configurada en UpsertRequest.Target Property. | Contiene los datos que se utilizarán para Create o Update . |
Aunque estas solicitudes se procesan en el servidor como se describe anteriormente, puede pensarlo de esta manera:
- Si el registro existe: El conjunto de datos en el cuerpo de la solicitud para esos valores clave alternativos en la URL se eliminaron, así que no tiene sentido incluirlos. Esta práctica garantiza que no pueda actualizar los valores clave alternativos de un registro cuando usa esos valores clave alternativos para identificarlo. Puede cambiar los valores de clave alternativa utilizando la clave principal o un conjunto diferente de claves alternativas.
- Si el registro no existe: Cualquier valor clave alternativo establecido en el cuerpo de la solicitud se usa para crear el nuevo registro, incluso si los datos son diferentes a los valores especificados por las claves alternativas en la URL. Si no hay datos clave alternativos en el cuerpo de la solicitud, los datos clave alternativos de la URL se copian en el cuerpo de la solicitud. Para evitar una situación en la que los valores clave en la URL y los valores clave correspondientes en el cuerpo no coincidan, es mejor no incluirlos en el cuerpo.
Uso de la API web
Con la API web, los mensajes Upsert
y Update
se inician usando http PATCH
frente a un recurso EntitySet
especificado e identificado por las claves en la URL.
La diferencia entre Upsert
y Update
se define por si el encabezado de solicitud If-Match: *
está incluido. Si el encabezado de solicitud If-Match: *
está incluido y ningún recurso coincide con los valores clave en la URL, la solicitud devuelve un código de estado 404 Not Found
. El encabezado de solicitud If-Match: *
asegura que la solicitud PATCH
sea una operación Update
.
Si no se incluye el encabezado de la solicitud If-Match: *
, la solicitud PATCH
se trata como una Upsert
y se crea un nuevo registro si no hay registros que coincidan con las claves que se encuentran en las URL. Sin embargo, a diferencia del SDK, la respuesta no le indica si se creó un registro. La respuesta de estado es 204 No Content
en cualquier caso.
Si incluye un encabezado de solicitud Prefer: return=representation
, el sistema devuelve un estado 201 Created
para Create
y un estado 200 OK
para Update
. Agregar este encabezado agrega una operación adicional Retrieve
por lo que tiene un impacto en el rendimiento. Si utiliza esta opción, asegúrese de que la opción de consulta $select
que agregue solo incluya el valor de clave principal. Más información:
Con una solicitud PATCH
también puede incluir el encabezado de solicitud If-None-Match: *
para bloquear un Update
si solo desea crear registros. Más información:Limitar operaciones de upsert.
Código de ejemplo de API web
Los siguientes ejemplos muestran operaciones Upsert
utilizando una tabla con dos columnas de clave alternativa:
Crear con Upsert
Esta solicitud crea un registro.
Solicitud:
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" }
Respuesta:
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)
Actualizar con Upsert
Esta solicitud actualiza el registro creado por la solicitud anterior.
Solicitud:
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" }
Respuesta:
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)
Nota
La respuesta es idéntica para las operaciones Crear o Actualizar.
Create con Upsert y preferencia return=representation
Cuando usa el encabezado Prefer: return=representation
puede obtener un código de estado diferente en la respuesta para indicar si el registro se creó o actualizó.
La siguiente solicitud crea un nuevo registro y devuelve el estado 201 Created
.
Solicitud:
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" }
Respuesta:
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"
}
Actualizar con Upsert y preferencia devolución=representación
Esta solicitud actualiza el registro creado por la solicitud anterior y devuelve el estado 200 OK
para mostrar que se trataba de una operación de actualización.
Solicitud:
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" }
Respuesta:
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"
}
Uso del SDK para .NET
Su aplicación de cliente utiliza IOrganizationService.Execute Method con una instancia UpsertRequest que tiene el conjunto Target Property con una instancia Entity que contiene los datos para una operación Create
o Update
. La instancia Entity normalmente tendrá Entity.KeyAttributes Property configurada con valores utilizados para identificar el registro mediante claves alternativas.
UpsertResponse.RecordCreated Property le dice si el registro fue creado, y UpsertResponse.Target contiene una referencia al registro que se creó o actualizó.
Código de muestra de SDK para .NET
El archivo SampleMethod.cs en la muestra Insertar registro usando Upsert contiene el siguiente método ProcessUpsert
para aplicar el mensaje UpsertRequest
en los contenidos de un archivo XML para crear nuevos registros o actualizar los que ya existen.
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;
}
}
}
Vea también
Uso del seguimiento de cambios para sincronizar los datos con sistemas externos
Definir claves alternativas para una tabla
Usar una clave alternativa para hacer referencia a un registro
Nota
¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)
La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).