Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Para obtener el mejor rendimiento al ejecutar operaciones en varias filas de una tabla de Microsoft Dataverse, use uno de los siguientes mensajes de operación masiva:
-
CreateMultiple: crea múltiples registros del mismo tipo en una sola solicitud. -
UpdateMultiple: actualiza múltiples registros del mismo tipo en una sola solicitud. -
UpsertMultiple: crea o actualiza varios registros del mismo tipo en una sola solicitud. -
DeleteMultiple: únicamente para tablas elásticas. Elimina múltiples registros del mismo tipo en una sola solicitud.
Nota
Para obtener instrucciones sobre las opciones al realizar operaciones masivas, como cuándo usar estas API en comparación con las API por lotes, como ExecuteMultiple, consulte Optimización del rendimiento para las operaciones masivas.
Ejemplos
Los siguientes ejemplos de código muestran cómo usar los mensajes de operación masiva. Puede descargar los ejemplos de github.com/microsoft/PowerApps-Samples:
- Ejemplo: SDK para .NET Utilizar operaciones masivas
- Ejemplo: API Web usar operaciones en masa
- Código de ejemplo de tablas elásticas
CreateMultiple
Crea múltiples registros del mismo tipo en una sola solicitud.
Usa la clase 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
Actualiza múltiples registros del mismo tipo en una sola solicitud.
Al igual que al actualizar registros individuales, los datos que envíe mediante UpdateMultiple deben contener solo los valores que está cambiando. Para obtener más información, consulte Actualización de registros con SDK para .NET y actualización de registros con la API web.
Usa la clase 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 en el parámetro UpdateMultiple Targets
UpdateMultiple no admite varios registros con la misma clave principal ni valores de clave alternativos en la carga. Cuando más de un registro en el parámetro Targets se identifica de forma única mediante un primario o clave alternativa, la operación se realiza solo en el primer registro. La operación ignora cualquier registro posterior con los mismos valores de clave en la carga útil.
Este comportamiento es diferente de UpsertMultiple.
UpsertMultiple
Use Upsert para integrar datos con orígenes externos cuando no sepa si la tabla existe en Dataverse. Las operaciones Upsert frecuentemente dependen de claves alternativas para identificar registros. Utilice UpsertMultiple para realizar operaciones de Upsert en masa.
Usa la clase UpsertMultipleRequest.
Este método UpsertMultipleExample estático depende de una tabla samples_bankaccount que tiene una columna de cadena con el nombre samples_accountname configurada como clave alternativa. También tiene una columna de cadena llamada samples_description. Este código utiliza el Constructor de entidad que establece keyName y keyValue para especificar el valor de clave alternativa.
/// <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")}");
}
}
Salida:
Record Updated
Record Created
La creación o actualización de un registro en este ejemplo depende de si existen registros con el valor sample_keyattribute coincidente. No se devuelven datos para indicar si se creó o actualizó un registro.
Ejemplos de SDK
En Ejemplo: SDK para .NET Uso de operaciones masivas, busque el proyecto UpsertMultiple.
Disponibilidad
UpsertMultiple está disponible para tablas que admiten CreateMultiple y UpdateMultiple. Este soporte incluye todas las tablas elásticas. Las consultas que se encuentran en Disponibilidad con tablas estándar no devuelven resultados para UpsertMultiple, pero puede usarlos para detectar si una tabla admite y CreateMultipleUpdateMultiple.
Estas consultas no devuelven resultados para el UpsertMultiple mensaje. Tabla que admite tanto a CreateMultiple como a UpdateMultiple y soporta UpsertMultiple.
Registros duplicados en el parámetro UpsertMultiple Targets
UpsertMultiple no admite varios registros con la misma clave principal ni valores de clave alternativos en la carga. Cuando más de un registro del Targets parámetro se identifica de forma única mediante una clave principal o alternativa, UpsertMultiple devuelve un error.
Este comportamiento es diferente de UpdateMultiple.
EliminarMúltiples
Elimine varias filas de datos en tablas elásticas con una sola solicitud.
Use la clase OrganizationRequest porque el SDK para .NET no tiene ninguna DeleteMultipleRequest clase. Para obtener más información, consulte Uso de mensajes con el SDK para .NET.
El siguiente DeleteMultipleExample método estático usa el DeleteMultiple mensaje con la clase OrganizationRequest para eliminar varias filas de la contoso_SensorData tabla elástica utilizando la clave alternativa partitionid para identificar de forma única las filas.
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);
}
Disponibilidad de DeleteMultiple
DeleteMultiple solo se admite para tablas elásticas. Las tablas elásticas no admiten el comportamiento en cascada de relaciones de tabla, lo que puede dar lugar a tiempos de ejecución impredecibles para las operaciones de eliminación. Si usa DeleteMultiple en una tabla estándar, obtiene el error: DeleteMultiple has not yet been implemented.
Ejemplos de DeleteMultiple
Puede encontrar código de muestra en GitHub en github.com/microsoft/PowerApps-Muestras:
- Código de ejemplo de tablas elásticas
- En Muestra: SDK para .NET, Usar operaciones masivas o Muestra: API web, Usar operaciones masivas, cambie el archivo de configuración
Settings.csy elija la opciónUseElastic.
Uso de tablas estándar y elásticas
Las tablas estándar y elásticas obtienen un aumento significativo del rendimiento cuando se emplean mensajes de operaciones masivas, pero deben usarse de forma diferente. En la tabla siguiente se resumen las diferencias.
| Diferencia | Estándar | Elástico |
|---|---|---|
| Número de registros | Las operaciones son más eficientes con una mayor cantidad de registros. No hay un límite en el número de registros, pero sí hay límites de tamaño del mensaje y de tiempo. Envíe 100 a 1000 registros a la vez. | Enviar 100 registros a la vez. |
| Comportamiento ante errores | Todas las operaciones retroceden en caso de error. | El éxito parcial es posible. |
| Disponibilidad | No todas las tablas estándar admiten estos mensajes. | Hay mensajes disponibles para todas las tablas elásticas. |
| EliminarMúltiples | No disponible. Use en cambio la SDK clase BulkDeleteRequest o la API web Acción BulkDelete. Más información sobre cómo eliminar datos de forma masiva. | Usar la clase DeleteMultipleRequest del SDK o la acción DeleteMultiple de la API Web |
El uso de tablas estándar y elásticas es diferente porque las tablas estándar usan Azure SQL y admiten transacciones. Las tablas elásticas usan Azure Cosmos DB, que no admite transacciones, pero administra grandes cantidades de datos en niveles altos de rendimiento con baja latencia. Las siguientes secciones ofrecen más detalles. Obtenga más información sobre las operaciones masivas en tablas elásticas.
Número de registros
La cantidad de registros que debe incluir con cada solicitud depende de si usa tablas estándar o elásticas.
Propina
Tanto las tablas estándar como las elásticas tienen un mayor rendimiento cuando envía mensajes de operaciones masivas en paralelo.
Número de registros con tablas estándar
Las operaciones masivas en tablas estándar están optimizadas para funcionar en varias filas en una sola transacción. Las operaciones se vuelven más eficientes y el rendimiento aumenta en general, a medida que aumenta el número de operaciones por solicitud. Esta optimización también hace que los pasos del complemento que están registrados para la operación masiva sean más eficaces. Cada vez que se invoca un complemento para una sola operación, el proceso requiere algunos milisegundos para invocar la clase del complemento que contiene la lógica. Al registrar un complemento para un mensaje de operación masiva, la clase se invoca una vez y puede procesar todas las operaciones de forma más eficaz. Aprenda a escribir complementos para CreateMultiple y UpdateMultiple.
Esta ventaja de rendimiento le anima a enviar el mayor número de registros que puede en cada solicitud. Sin embargo, a medida que aumenta la cantidad de registros, el tamaño de la solicitud también aumenta y lleva más tiempo procesar. Eventualmente, te encuentras con los límites de tamaño y tiempo del mensaje. Si alcanza estos límites, toda la operación falla. No hay un límite establecido en la cantidad de registros que puede enviar. Es posible que tenga que experimentar para encontrar el mejor número. Por lo general, de 100 a 1000 registros por solicitud es un lugar razonable para empezar si el tamaño de los datos de registro es pequeño y no hay complementos. Los tipos de errores que se pueden encontrar normalmente se pueden solucionar mediante el envío de menos registros con cada solicitud. Incorpore la capacidad de configurar el número de entidades enviadas para poder adaptarse enviando menos.
Número de registros con tablas de Elastic
Debido a que no hay transacción con tablas elásticas, no hay beneficio de rendimiento al tratar de enviar un gran número de registros por solicitud. Envíe 100 operaciones por solicitud y envíe solicitudes en paralelo para lograr el máximo rendimiento.
Comportamiento ante errores
El comportamiento cuando se producen errores es diferente en función de si utiliza tablas estándar o elásticas.
Gestión de errores con tablas estándar
Cualquier error que ocurra en una operación masiva con una tabla estándar hace que se revierta toda la operación. Solo use operaciones masivas en tablas estándar cuando tenga un alto grado de confianza de que todas las operaciones tendrán éxito. Para permitir que el conjunto de operaciones revierta si se produce un error en la operación masiva, considere usar la clase ExecuteMultipleRequest del SDK o la API web $batch. Si la tasa de éxito de los intentos iniciales es baja, esta estrategia genera un peor rendimiento. Solo use esta estrategia alternativa cuando espere que la mayoría de las operaciones funcionen correctamente.
Comportamiento del error con tablas dinámicas
Con las tablas elásticas, una operación masiva puede tener éxito parcial. Puede usar los detalles del error para identificar qué registros fallaron.
Cuando usa el SDK para realizar una operación masiva en una tabla elástica, se lanza una FaultException de tipo OrganizationServiceFault si ocurre un error. Use el código siguiente para obtener el estado 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; }
}
Disponibilidad
La disponibilidad de mensajes en operaciones masivas depende de si utiliza tablas estándar o tablas elásticas. Todas las tablas elásticas admiten los mensajes CreateMultiple, UpdateMultiple, UpsertMultiple y DeleteMultiple.
Disponibilidad con tablas estándar
Puede usar los mensajes de operaciones en bloque CreateMultiple y UpdateMultiple para tablas personalizadas y muchas tablas estándar comunes, pero no con todas. Pruebe si las tablas estándar individuales admiten estos mensajes. Los siguientes ejemplos muestran cómo hacerlo.
Utilice este método estático para detectar si una tabla determinada admite CreateMultiple o 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);
}
Tuberías de mensajes combinadas
Cada mensaje de operación masiva tiene un mensaje correspondiente que funciona en filas individuales: Create, Updatey Delete. Estos mensajes existen desde hace mucho tiempo y muchas organizaciones tienen una lógica personalizada que depende de los eventos que ocurren cuando se usan estos mensajes.
Un requisito clave de los mensajes de operación masiva es que las organizaciones no deben mantener la lógica personalizada en dos lugares. Para tener la misma lógica personalizada y mantenerla en un solo lugar, Dataverse combina las canalizaciones de procesamiento de mensajes para estos mensajes. ¿Qué significa esta combinación?
Cuando se usa un mensaje de operación masiva, el evento respectivo
CreateyUpdateocurre para cada instancia de Entity en el parámetroTargets. Todos los complementos u otros controladores de eventos para los eventos individuales correspondientes siguen funcionando como siempre. No necesita escribir nuevos complementos para administrar los eventos generados por estos mensajes.Cuando se usa un único mensaje de operación, el evento de operación masiva correspondiente se produce con una EntityCollection que contiene una sola instancia de Entity pasada en el
Targetsparámetro . Puede mover cualquier lógica que responda a eventos de operación única a los eventos de operación masiva más eficientes y la lógica se aplica tanto para operaciones únicas como múltiples.
Antes de la introducción de los mensajes de operaciones masivas, toda la lógica personalizada estaba en los mensajes de operaciones individuales. Esa lógica se sigue aplicando cuando las aplicaciones cliente usan los mensajes de operación masiva. En el caso de las tablas que se usan con operaciones masivas de gran volumen, mueva cualquier lógica sincrónica de eventos de mensaje únicos a eventos de operación masiva. Si está introduciendo una nueva lógica, use los eventos de operación masiva en lugar de los eventos de operación única.
Precaución
Con este diseño, la lógica duplicada se puede aplicar potencialmente en versiones únicas y múltiples de eventos. Dataverse no intenta evitar esto porque no puede conocer su intención.
Es su responsabilidad asegurarse de que la misma lógica aplicada para la versión única de los eventos se migre a la versión múltiple del evento y se elimine de la versión única del evento. De lo contrario, la lógica se aplica dos veces.
Aprenda a escribir complementos para CreateMultiple y UpdateMultiple.
Limitaciones
Tenga en cuenta las siguientes limitaciones cuando utilice mensajes de operaciones masivas.
Tamaño del mensaje y límites de tiempo
En el caso de las tablas estándar, obtendrá un mejor rendimiento al enviar más registros con cada solicitud. Sin embargo, el tamaño de la carga y el tiempo necesario para procesar la operación limitan el número de registros que puede enviar.
Límites de tamaño del mensaje
Si registra un plugin para cualquier mensaje, es posible que encuentre el error "Tamaño del mensaje superado al enviar el contexto a la caja de arena" cuando el tamaño total de la solicitud supera los 116,85 MB. Cuando se usan mensajes de operación masiva, puede alcanzar este límite más fácilmente porque se envían cargas más grandes.
Este error no se produce si no ha registrado un plug-in para el evento. Para evitar el error, deshabilite los complementos o envíe la solicitud mediante el BypassCustomPluginExecution parámetro opcional.
Límites de tiempo
Si usa Dataverse ServiceClient, podría producirse este error:
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.
El tiempo de espera predeterminado establecido mediante ServiceClient es de cuatro minutos, que es largo para cualquier operación sincrónica. Puede cambiar este valor mediante la propiedad static ServiceClient.MaxConnectionTimeout . El tiempo de espera predeterminado mediante CrmServiceClient es de dos minutos.
Nota
Antes de aumentar los límites de tiempo, considere la posibilidad de reducir el número de registros que se pasan en el Targets parámetro.
No compatible para su uso en complementos
Actualmente, Dataverse no admite el uso de mensajes de operación masiva en el código del complemento. Para obtener más información, consulte No usar tipos de solicitud por lotes en complementos y actividades de flujo de trabajo.
Sin embargo, debe escribir complementos para los mensajes CreateMultiple y UpdateMultiple como se describe en Escribir complementos para CreateMultiple y UpdateMultiple.
Solucionar errores habituales
Si se producen errores al usar operaciones masivas, consulte los siguientes artículos:
- Solucionar problemas de errores de operación masiva de Dataverse
- Solucionar problemas de errores de cliente de Dataverse
Preguntas frecuentes
Si no encuentra una respuesta a las preguntas que tiene sobre el uso de mensajes de operaciones masivas en este artículo, use el botón en la parte inferior de la página para Enviar y ver comentarios para esta página. Necesita una cuenta de GitHub para enviar comentarios.
¿Se fusionarán las lógicas Retrieve y RetrieveMultiple?
Microsoft no tiene previsto cambiar el comportamiento de los mensajes Retrieve y RetrieveMultiple. Estos mensajes han sido mensajes independientes durante muchos años, y los desarrolladores siempre necesitan mantener la lógica para ellos por separado. Intentar fusionar la canalización de mensajes para ellos sería muy problemático. Además, evite aplicar lógica personalizada para estos mensajes debido al impacto que pueden tener en el rendimiento.
¿Cómo se aplican los límites de API?
Se aplican dos tipos de límites de API. Los mensajes de operación masiva no proporcionan ninguna forma de eludir ninguno de los dos tipos.
Límites de protección de servicio
Como se describe en Límites de la API de protección del servicio, los límites tienen tres facetas. Dos de estos límites se evalúan en una ventana deslizante de cinco minutos y se aplican al usar estos mensajes.
- Número de solicitudes: cada mensaje de operación masiva cuenta como una sola solicitud que se acumula hasta el límite de 6000 solicitudes por usuario, por servidor, durante la ventana de cinco minutos. Debido a que estas solicitudes agrupan operaciones individuales, se reduce la probabilidad de alcanzar este límite.
- Tiempo de ejecución: debido a que cada solicitud de mensaje de operación masiva generalmente toma más tiempo, y si está enviando solicitudes en paralelo, es más probable que alcance el límite de tiempo de ejecución, eso es 20 minutos por usuario, por servidor, durante la ventana de cinco minutos.
Límites de solicitud de Power Platform (derecho de API)
Estos límites se basan en los cambios de datos: operaciones Create, Update y Delete. Cada elemento incluido en el parámetro Targets de una solicitud de operación masiva se acumula en este límite.
Más información sobre asignaciones y límites de solicitudes
Consulte también
Tablas elásticas
Escribir complementos para CreateMultiple y UpdateMultiple
Ejemplo: SDK para .NET Utilizar operaciones masivas
Ejemplo: API Web usar operaciones en masa
Ejemplo: complementos CreateMultiple y UpdateMultiple
Utilice mensajes con el SDK para .NET
Optimice el rendimiento para operaciones masivas