miércoles, 12 de agosto de 2009

Eliminación masiva de registros en MSCRM

Muchas veces necesitamos eliminar toda la información de una entidad específica. Si son pocos registros, no hay problema, los eliminamos de forma manual con el propio CRM.
Ahora, si los registros son muchos, Microsoft CRM nos da la posibilidad de llamar a unos trabajos asíncronos de eliminación, de forma que podemos dispararlos, y dejarlos hasta que acaben de eliminar todos los registros.
Recomiendo no eliminar nunca registros "a mano" en la base de datos SQL salvo que sea extrictamente necesario. Además tener en cuenta que si se borra directamente en SQL Server, toda la funcionalidad que se le haya definido a la entidad en cuando a relaciones en cascada, los workflows, y los plugins, no se dispararán. Además, como saben, no esta soportada la eliminación de registros directamente en la base de datos.

La siguiente función hace exactamente eso, borra todos los registros de una entidad a traves de un trabajo del sistema asíncrono. Está hecho de una forma soportada y documentada en la SDK de MSCRM 4.0:


public static void BorradoMasivo(string crmServerUrl, string orgName, string Entidad, string Usuario, string Password, string Dominio)
{
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.OrganizationName = orgName;
CrmService service = new CrmService();
service.Credentials = new System.Net.NetworkCredential(Usuario, Password,Dominio);
service.Url = crmServerUrl;
service.CrmAuthenticationTokenValue = token;

QueryExpression bulkDeleteQuery = new QueryExpression();
bulkDeleteQuery.EntityName = Entidad;

BulkDeleteRequest bulkDeleteRequest = new BulkDeleteRequest();
bulkDeleteRequest.JobName = "Eliminacion de: " + Entidad;
bulkDeleteRequest.QuerySet = new QueryBase[] { bulkDeleteQuery };

bulkDeleteRequest.StartDateTime = new CrmDateTime();
bulkDeleteRequest.StartDateTime.Value = DateTime.Now.ToString();

bulkDeleteRequest.RecurrencePattern = string.Empty;
bulkDeleteRequest.SendEmailNotification = false;
Guid[] emptyRecipients = new Guid[0];
bulkDeleteRequest.ToRecipients = emptyRecipients;
bulkDeleteRequest.CCRecipients = emptyRecipients;

BulkDeleteResponse bulkDeleteResponse = (BulkDeleteResponse)service.Execute(bulkDeleteRequest);
}

Este proceso puede tardar mucho en caso de haber muchos miles (o millones) de registros.

A medio camino del "delete" en la base de datos y de la utilización de la SDK, existe una posibilidad, no soportada también, de eliminar registros.
Al eliminar un registro en MSCRM 4.0, realmente no se elimina de la base de datos, sino que simplemente se marca como para borrar poniendo el campo "deletionstatecode=2", para que luego el proceso asíncrono se encargue de eliminar todos los registros marcados. De esta forma podríamos "eliminar" registros del CRM a traves de un "UPDATE" en la base de datos. Esto no esta soportado, así que esto se debería probar que se eliminan correctamente.

Así, por ejemplo, podríamos eliminar todas las Cuentas:

UPDATE AccountBase SET DeletionStateCode=2

Las eliminaciones masivas de registros pueden ser muy lentas si se hacen de forma soportada, pero para utilizar formas no soportadas, se debería estar muy seguro de lo que se hace y realizar exhaustivas pruebas de que eso funcion correctamente y no tiene consecuencias secundarias.

Espero pueda servirles,

Saludos

4 comentarios:

  1. ola buenas me encanta tu blog m es de mucha utilidad, pero querria saber si dispones de alguna información de como hacer campos heredados con datos persistentes entre diferentes entidades . algo asi como si fueran variables de sesion, un saludo y gracias

    ResponderEliminar
  2. Hola, no estoy seguro si he entendido correctamente lo que me dices, pero tienes una funcionalidad para "heredar" valores de atributos de una entidad a otra, definiéndola en la relación ("relationship") en "asignaciones". Allí puedes definir un mapeo de campos desde un "padre" a un "hijo". Sino deberías desarrollarte algo especial, como un Assembly (plugin o workflow) o un desarrollo web.

    Un saludo

    ResponderEliminar
  3. Hola Demian, te felicito por tu blog, es verdaderamente útil. Sabes, quisiera saber si es que existe alguna manera segura de dejar mi base de datos desde 0 y que no vaya a afectar el correcto funcionamiento de mi crm dynamics. Resulta que mi base tiene información muy antigua que quiero eliminar, además de muchas campañas de prueba. Mi ideal es dejarla como si el sistema se hubiera instalado recién. Puedo recurrir a algunas tareas de sqlserver, generar los scripts que me recreen la base nuevamente y vacia pero me imagino que debe haber data en algunas tablas que no debiera tocar si es que pretendo que el sistema siga andando... bueno, eso.. gracias por todo lo publicado y por la posible ayuda.

    ResponderEliminar
    Respuestas
    1. Hola, lo mejor que puedes hacer es o bien eliminarlo a mano (si es posible por el volumen de datos), o bien crearte una aplicación .NET que consulte y elimine todos tus registros.
      Otra opción podría ser el crearte una nueva instancia de CRM (una nueva organización, o un nuevo servidor), y luego exportar las personalizaciones e importarlas en el nuevo. Luego solo te quedaría crear los usuarios, unidades de negocio, equipos y asignarles los roles de seguridad.
      Si tu implementación tiene algunos otros desarrollos, por ahí te toque configurar algunas cosas mas.
      un saludo,

      Eliminar