miércoles, 15 de septiembre de 2010

Buenas prácticas con los metadatos

Casi siempre en nuestros desarrollos necesitamos ir a los metadatos del CRM, para ver determinados atributos, tamaños, personalizaciones, etc.
Esto nos hará nuestros desarrollos mas dinámicos y adaptables, además de ser mas "inteligentes".
Para esto hay varias formas de acceder a los metadatos, y es necesario que se haga de una forma que afecte lo menos posible al rendimiento tanto de nuestro desarrollo como del servidor de CRM.
Es por esto que me pregunté que diferencias de rendimiento podría haber si en vez de recoger un atributo mediante el mensaje "RetrieveAttribute", recojo la entidad completa mediante el mensaje "RetrieveEntity" o incluso recogiendo todas las entidades con el "RetrieveAllEntities".
Para esto me desarrollé la siguiente aplicación de consola que me muestra las diferencias de tiempos de respuesta:
CrmAuthenticationToken token = new CrmAuthenticationToken();
            token.OrganizationName = "AdventureWorks";

            token.AuthenticationType = 0;

            MetadataService metadataService = new MetadataService();
            metadataService.Url = "http://192.168.1.22:5555/MSCRMServices/2007/MetadataService.asmx";
            metadataService.CrmAuthenticationTokenValue = token;
            metadataService.Credentials = new System.Net.NetworkCredential("usuario", "contraseña", "CRM");
            
            RetrieveAllEntitiesRequest allEntitiesRequest = new RetrieveAllEntitiesRequest();
            allEntitiesRequest.RetrieveAsIfPublished = false;
            allEntitiesRequest.MetadataItems = MetadataItems.EntitiesOnly;

            DateTime dtinicioall = DateTime.Now;
            RetrieveAllEntitiesResponse allEntitiesResponse = (RetrieveAllEntitiesResponse)metadataService.Execute(allEntitiesRequest);
            TimeSpan dtall = DateTime.Now.Subtract(dtinicioall);
            Console.WriteLine("Tiempo en ejecutar RetrieveAllEntitiesResponse:"+dtall.TotalMilliseconds.ToString());

            RetrieveEntityRequest entityRequest = new RetrieveEntityRequest();
            entityRequest.RetrieveAsIfPublished = false;
            entityRequest.LogicalName = "contact";
            entityRequest.EntityItems = EntityItems.All;

            DateTime dtiniciocontact = DateTime.Now;
            RetrieveEntityResponse entityResponse = (RetrieveEntityResponse)metadataService.Execute(entityRequest);
            TimeSpan dtcontact = DateTime.Now.Subtract(dtiniciocontact);
            Console.WriteLine("Tiempo en ejecutar RetrieveEntityResponse de contact:" + dtcontact.TotalMilliseconds.ToString());


            DateTime dtinicioaccount = DateTime.Now;
            entityResponse = (RetrieveEntityResponse)metadataService.Execute(entityRequest);
            TimeSpan dtaccount = DateTime.Now.Subtract(dtinicioaccount);
            Console.WriteLine("Tiempo en ejecutar RetrieveEntityResponse de account:" + dtaccount.TotalMilliseconds.ToString());


            RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest();
            attributeRequest.EntityLogicalName = "contact";
            attributeRequest.LogicalName = "firstname";
            attributeRequest.RetrieveAsIfPublished = false;

            DateTime dtiniciofirstname = DateTime.Now;
            RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)metadataService.Execute(attributeRequest);
            TimeSpan dtfirstname = DateTime.Now.Subtract(dtiniciofirstname);
            Console.WriteLine("Tiempo en ejecutar RetrieveAttributeResponse de firstname de contact:" + dtfirstname.TotalMilliseconds.ToString());


            attributeRequest = new RetrieveAttributeRequest();
            attributeRequest.EntityLogicalName = "account";
            attributeRequest.LogicalName = "name";
            attributeRequest.RetrieveAsIfPublished = false;

            DateTime dtinicioname = DateTime.Now;
            attributeResponse = (RetrieveAttributeResponse)metadataService.Execute(attributeRequest);
            TimeSpan dtname = DateTime.Now.Subtract(dtinicioname);
            Console.WriteLine("Tiempo en ejecutar RetrieveAttributeResponse de name de account:" + dtname.TotalMilliseconds.ToString());

            Console.ReadLine();

Bien, esto me devuelve como resultado lo siguiente (los tiempos están en milisegundos):


Lo que se recoge claramente allí es que por ejemplo es mucho mas óptimo el recoger un solo atributo que recoger toda la entidad de "account", pero que pasaría si tenemos que recoger 15 atributos diferentes de "account"?. Allí ya nos convendría recoger la entidad completa...

Conclusión: es claramente recomendable el ejecutar los mensajes mas "ajustados" a lo que se quiera realizar, pero teniendo en cuenta la escalabilidad de nuestra aplicación, y el funcionamiento que se quiere como resultado.

Un abrazo,

No hay comentarios:

Publicar un comentario