Desarrollo de CRM Callouts en Visual Studio 2005

Hasta ahora la mayoría de los que hacemos desarrollos para Microsoft CRM 3.0 nos veíamos obligados a mantener en instalado en nuestro equipo Visual Studio 2003, además de Visual Studio 2005. El motivo era el desarrollo de callouts, ya que estos deben compilarse utilizando .NET 1.1 por que se ejecutan dentro del mismo proceso de IIS que el servidor CRM (Aplicación hecha en .NET Framework 1.1). Y como en Visual Studio 2005 no hay ninguna opción de serie que permita indicar que queremos compilar utilizando la versión 1.1 de .NET, nos veíamos obligados a seguir utilizando Visual Studio 2003 para crear CRM Callouts.


Bueno, pues ya podéis empezar a desinstalarlo, si queréis, por que gracias a una plantilla de proyecto para callouts creada por Arash ya podemos desarrollar callouts en Visual Studio 2005. Para poder utilizarla sólo necesitamos tener instalado el runtime de .NET framework 1.1, además de Visual Studio 2005, y ejecutar el instalador que podéis descargar también desde el blog de Arash. La plantilla de proyecto para Callouts incluye además todo lo necesario para desarrollar callouts, el fichero calloutbase.dll del CRM 3.0, un fichero con código de ejemplo y el fichero de configuración de callouts en blanco. En resumen, con esta plantilla tenemos todo lo necesario para desarrollar un callout en Visual Studio 2005, una gran ayuda sin duda.



Si queréis saber más leeros el artículo de Arash en su blog donde presenta la plantilla para callouts y da más detalles sobre cómo instalarla y utilizarla. Os dejo que voy a desinstalar Visual Studio 2003.


Saludos,


Marco Amoedo

Pequeñas novedades y algo más sobre mapas

Pasan los días y seguimos sin saber nada del prometido cliente móvil open source, la verdad es que ya me está tardando probarlo. Pero mientras tanto os recomiendo que le echéis un vistazo a un ejemplo que ha dejado Barry Givens en CRM SandBox, en este ejemplo se utilizan los mapas de Virtual Earth para mostrar información sobre disponibilidades de servicios. Sigue la misma línea de integración que habíamos hecho nosotros en el ejemplo que postee antes de las vaciones sobre integrar mapas en MS CRM, pero está mucho más currado, de verdad que vale la pena echarle un vistazo.


También, desde hace unos días, está disponible online en MSDN la versión 3.0.5 del SDK de Microsoft Dynamics CRM, con lo que ya podemos consultarlo desde el navegador web a través de Internet, además del formato de fichero de ayuda para consulta offline.


Últimamente me he encontrado con bastante gente interesada en conseguir ocultar campos de un formulario según el rol de usuario que lo abra, y la verdad es que no es una labor sencilla, pero tampoco imposible. En el blog de Ronald Lemmen hay un ejemplo muy bueno para hacer esto, y C360 vende una herramienta con una integración impresionante con Microsoft CRM que consigue lo mismo.


Bueno, por hoy os dejo, no he dedicado tiempo al blog estos días porque me encuentro involucrado en un complejo proyecto que me absorbe la mayor parte de mi tiempo libre… me estoy mudando de casa!! Y no veáis la de cosas que encuentras en una mudanza, ¿Alguien quiere un libro de programación en COBOL?


Un saludo,


Marco Amoedo

Mejorar la velocidad de las llamadas a los Servicios Web

Si de algo pecan los servicios web es que pueden resultar demasiado lentos para trabajos que supongan una carga intensiva, como por ejemplo, la importación masiva de registros a Microsoft Dynamics CRM. Recientemente he tenido algunos problemillas por culpa de esto, y buscando por Internet he encontrado este post de Aaron Elder (Invoke Systems), en el que nos proponen formas de aumentar la velocidad de las llamadas a los servicios web. Os recomiendo que le echéis un vistazo, sobre todo si estáis realizando algún desarrollo que haga una utilización intensiva de los servicios web de Microsoft CRM.


En el post se proponen varios métodos sencillos que permiten optimizar las llamadas a servicios web en .NET, y hacen una comparación de tiempos donde podemos comprobar la mejoría. El mejor resultado se obtiene utilizando el modo Unsafe en la llamada al servicio web junto con algunas optimizaciones de IIS, pero no lo uséis a la ligera ya que el modo Unsafe permite que usuarios con distintas credenciales utilicen una misma conexión para hacer llamadas a los servicios web. En el propio post ya advierten sobre estos peligros, aunque como bien explican, para el caso de una herramienta de importación masiva que utiliza un único usuario de CRM no supone ningún problema.


Ejemplo:







1
2
3
4
CrmService crm = new CrmService();
crm.Credentials = System.Net.CredentialCache.DefaultCredentials;
crm.Url = «http://192.168.1.25/MSCRMServices/2006/CrmService.asmx»;
crm.UnsafeAuthenticatedConnectionSharing = true; //Modo Unsafe Activado


Saludos,


Marco Amoedo

Se terminaron las vacaciones

Aquí estoy de nuevo, con las pilas cargadas después de unos días de descanso. Como veis en Geeks.ms hemos migrado a Community Server 2.1, y aprovechando la coyuntura he decidido cambiar el aspecto visual del blog, espero que os guste. Además, después de unos problemillas técnicos, ya funcionan los foros de Geeks.ms con lo que tenemos un nuevo espacio donde aprender más sobre Microsoft Dynamics CRM.


No todo ha sido divertido en estas vacaciones, porque desgraciadamente algunos desalmados (por no decir algo más fuerte) se han dedicado a desatar una catástrofe natural en Galicia. No quiero entrar en más detalles sobre esto, ni ninguna polémica relacionada, sólo quiero aprovechar este espacio para dar las gracias a los cientos de personas que al ver llegar el fuego a las casas de sus vecinos se echaron al monte para ayudar en lo que pudiesen. Personalmente nunca me había visto en medio de un incendio, y menos un infierno como este en el que veíamos peligrar las casas de familiares y amigos, la experiencia ha sido impresionante. Os dejo unas fotos publicadas en la Voz de Galicia para que os hagáis una idea.


 


Dejando a un lado mis vacaciones y prácticas de bombero, volvamos al tema central del blog. Parece que en Microsoft también se han ido de vacaciones, porque todavía no se ha liberado el nuevo cliente móvil de CRM 3.0. A pesar de que, según se comentaba en un post del blog del equipo del CRM, debería de haber aparecido hace más de una semana. En ese mismo post también podemos enterarnos un poco más de las capacidades de este nuevo cliente móvil, básicamente, se trata de una aplicación web adaptada para dispositivos, con lo que aventaja en facilidad de instalación (sólo necesitamos tener un navegador web en el dispositivo) y funcionalidad (podemos acceder a todas las entidades, incluso las personalizadas) al cliente móvil que está disponible actualmente. Sin embargo, la desventaja está en la imposibilidad de trabajar sin conexión, ya que hemos de conectarnos por GPRS (o similares) a nuestro servidor. En este otro post de Sonoma Partners hay unas capturas de pantalla muy interesantes, os recomiendo echarle un vistazo. La verdad es que me está tardando poder probar este nuevo cliente, creo que será una herramienta de grandísima utilidad, y de código libre!!



Otra pequeña novedad, que se ha producido estos días, ha sido la liberación de versiones localizadas de CRM List Web Part para Sharepoint. Con lo que el “truco” que teníamos que hacer para conseguir instalar este web part en un Sharepoint en español ya no es necesario.


Bueno, por hoy os dejo. Espero poder seguir publicando cosas interesantes sobre Microsoft CRM y las estrategias CRM en general, tengo algunas ideas preparadas pero se admiten sugerencias., si queréis podéis utilizar el formulario de email del blog para hacer peticiones y sugerencias.


¿Qué os parece el nuevo cliente móvil? ¿Será un inconveniente o una ventaja el no poder trabajar desconectado?


Un Saludo,


Marco Amoedo

Vacaciones y Libros

Oficialmente estoy de vacaciones, así que durante esta quincena no publicaré nada en el blog. O por lo menos intentaré resistir la tentación. Me tomaré unos cuantos días de descanso por mi tierra, visitaré las Islas Cies, uno de nuestros pequeños paraísos, y procuraré estar alejado del ordenador.


 


Pero antes de irme de vacaciones os quería hacer una pequeña recomendación de libros que me han parecido muy útiles e interesantes. Se trata de “Adaptarse a la marea” de Eduardo Punset y de “Los 100 errores del CRM” de Pedro Reinares.


 


                       


 


Adaptarse a la Marea” es un libro ameno que trata de mostrar como algunos conceptos de la biología y la ciencia en general pueden aplicarse a la organización de empresas. El libro está escrito en un lenguaje claro (nada técnico), y trata de mostrar las implicaciones de la ciencia en las empresas mediante ideas y ejemplos, con esto quiero decir que no esperéis un manual de tipo “cómo hacer…”. Es más bien un libro que invita a reflexionar y a descubrir como la ciencia puede ayudar en la organización y gestión empresarial. Personalmente me han llamado mucho la atención algunos de los capítulos en los que se comentan temas como la percepción de la imagen de marca, las redes sociales y optimización de procesos.


 


Los 100 errores del CRM” debería ser un libro de obligatoria lectura para todos aquellos que participen en el diseño de una estrategia CRM y la implantación de un software CRM. Este libro no trata de definir lo que está bien en CRM, al revés, trata de mostrar los errores más comunes en estas estrategias para que podamos aprender y evitarlos. Este libro trata al CRM desde un punto de vista de organización empresarial, es bastante ameno, y tiene multitud de buenos y malos ejemplos de empresas muy conocidas. Personalmente, este libro me ayudó a tener más perspectiva empresarial sobre el marketing relacional y CRMs, que la perspectiva técnica propia de mi perfil. Recomiendo a todos aquellos que tengáis un perfil técnico que lo leáis, porque estoy seguro de que en vuestro trabajo os ayudará el conocer más a fondo otros puntos de vista del CRM.


 


Ya veis que no os recomiendo ningún libro técnico, ni ningún manual de Microsoft CRM, y es que como decía un profesor: “Los informáticos deben saber de todo, porque han de diseñar sistemas de información para todo”.Vamos, que no todo va a ser saber como hacer tal personalización, o como diseñar un despliegue de MS CRM, debemos de tener conocimientos de que es CRM en sí para poder dar la solución tecnológica adecuada a cada caso.


 


Un saludo, disfrutad del verano, o el invierno para la gente que lee esto desde el hemisferio sur. Nos vemos a la vuelta de las vacaciones.


 


Marco Amoedo Martínez

Integrar Mapas de Virtual Earth en Microsoft Dynamics CRM

Hoy vamos a ver un sencillo ejemplo de cómo integrar mapas en Microsoft Dynamics CRM aprovechando el API de VirtualEarth de Windows Live! Digo sencillo, porque es solo una burda muestra de las posibilidades que nos da este API para conseguir mostrar información geográfica en el CRM.


 


El objetivo es tener una pestaña en el formulario de cuentas donde poder visualizar un mapa centrado en la dirección de la cuenta. Es decir, un mapa centrado en la ubicación de nuestro cliente.


 


 


Para ello no tenemos más que crear una página web con el siguiente código:


 


<html xmlns=»http://www.w3.org/1999/xhtml» >


   <head>


      <title></title>


      <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″/>


      <script src=»http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js»>


</script>


      <script>


      var map = null;


           


      function GetMap()


      {        


         var pais = parent.document.forms[0].all.address1_country.DataValue;        


         var provincia = parent.document.forms[0].all.address1_stateorprovince.DataValue;


         var ciudad = parent.document.forms[0].all.address1_city.DataValue;        


        


         map = new VEMap(‘myMap’);


         map.LoadMap();


         if(ciudad!=») map.FindLocation(ciudad+‘, ‘+provincia+‘, ‘+pais);


         else map.FindLocation(‘Madrid, España’);         


      }  


     


      </script>


   </head>


   <body onload=»GetMap();»>


      <div id=’myMap’ style=»position:relative; width:auto; height:auto; «></div>


   </body>


</html>


 


Si os fijáis en el código veréis que mediante JavaScript accedemos a los valores de ciudad, provincia y pais del formulario de Cuenta del CRM. Para luego utilizarlos para fijar la posición del mapa. Al acceder a esos campos estamos utilizando cross-site scripting, por lo que tendremos que habilitar explícitamente esta opción en el IFrame.Si qureis saber más sobre el API y las funcionalidades de los mapas bajaros el SDK de Virtual Earth.


 


Para guardarla crearemos un directorio dentro del sitio web de Dynamics CRM con el objetivo de poder referenciar sencillamente la página en el IFrame que vamos a crear. En mi caso C:Archivos de ProgramaMS CRMCRMWebvemapsvemap.htm


 


Una vez guardada sólo nos resta acceder a Personalización de Entidades en Microsoft Dynamics CRM y abrir la entidad cuenta. Dentro de esta buscaremos el formulario principal y lo editaremos, añadiendo una nueva pestaña que contendrá una nueva sección, que a su vez contendrá el nuevo IFrame. En las propiedades del IFrame indicaremos la url de la página que hemos creado (ie: /vemaps/vemap.htm) y habilitaremos el cross-site scripting.


 


 


 


Guardamos los cambios, salimos y publicamos las personalizaciones, y ya podemos comprobar como al abrir una cuenta tenemos la nueva pestaña con el mapa centrado en su localización


 


Esto, es un sencillo ejemplo de las posibilidades que nos brindan los IFrames para integrar aplicaciones en el CRM, y de las posibilidades que nos da el API de Virtual Earth para integrar mapas en el CRM. Imaginad mostrar sobre un mapa la distribución geográfica de nuestros clientes, calcular rutas de visita para comerciales… hay un sinfín de posibilidades. ¿Se os ocurren más? ¿Alguna experiencia con Información Geográfica?


 


Espero que os haya gustado el ejemplo, un saludo


 


Marco Amoedo Martínez

Más ejemplos de como usar mal un CRM

Hace unos días José Alarcón, un compañero de Geeks, me comentaba los problemas que había tenido con su operadora de ADSL al querer modificar el servicio que le prestaban (podeís leerlo en su blog). Esto, junto con algunas otras experiencias, me ha hecho pensar en cómo muchas veces las empresas toman los sistemas CRM como una herramienta para controlar a su fuerza de ventas, y en el grave error que supone esto.


El caso es que Alarcón tenía una línea ADSL con Wanadoo que funcionaba perfectamente a una determinada velocidad, sin embargo, a la vista de las nuevas ofertas de 20MBs decidió cambiar. Como hombre precavido que es, llamó en varias ocasiones para consultar si era posible el cambio y si esto no interrumpiría el servicio, en todas ellas la respuesta fue positiva, el cambio se haría sin ningún corte del servicio. Algo que a cualquier persona en este mundo le parecería lo más lógico al no cambiar en ningún momento de operador, aunque ya sabemos que las operadoras de telecomunicaciones no suelen ser de este mundo. Sin embargo, ya sabéis lo que pasó, ese cambio tan sencillo del que le había asegurado no interrumpiría el servicio se convirtió en un mes sin conexión a Internet en su casa. El motivo fue algo tan sencillo como que el operador que hizo la transacción tramitó una baja y una nueva alta, en vez de realizar un simple cambio de servicio.


Lo que más extrañaba a Alarcón es el motivo por que el teleoperador había tramitado la baja y nuevo alta en vez de un cambio de servicio, y la verdad es que de buenas a primeras puede parecer ineptitud por parte del teleoperador. Pero seguramente, la culpa de esto no es otra que haber utilizado una herramienta CRM como un “gran hermano” de la fuerza de ventas. Me refiero, a que la empresa probablemente utiliza la información proporcionada al CRM por su fuerza de ventas como un instrumento de control de las actividades comerciales, por lo tanto, el CRM en vez de proporcionar la automatización de tareas y ayudar a la labor comercial, lo que hace es crear una fuerza de ventas que desconfía del CRM y se siente presionada. Con lo que el teleoperador en su afán por mejorar sus estadísticas de ventas, para mantener su trabajo o mejorar su sueldo, decidió que sería mejor apuntarse un alta que un simple cambio de servicio.


Otra cosa que puede resultar muy rara es que la empresa no se molestase en comprobar el motivo de una baja, o ni siquiera intentase la retención del cliente. Esto evidencia que de nuevo la empresa ha cometido un error de libro en el marketing relacional, no centra su estrategia en retener clientes sino en captarlos. Esto es una gran equivocación ya que normalmente es más barato retener un cliente que captarlo, y es el verdadero objetivo del CRM, hacer relaciones duraderas. Acaso no sería más barato haber hecho una llamada al cliente para conocer los motivos de la baja y tratar de evitarla (algo muy fácil en este caso ya que no era una baja deseada), que los gastos que genera la captación de un cliente (proceso de alta, modem/router adsl, etc…). Es más, no debemos dejar la retención del cliente para el momento en el que ya ha tomado la decisión de irse, la retención del cliente debe conseguirse día a día con la personalización del servicio y el trato adecuado.


Y ya para acabar de rematar la faena, como es posible que una vez detectado el caso la compañía no haya sido capaz de remediarlo. Parece increíble que la única solución propuesta haya sido la de continuar un proceso de alta normal (1mes), y sin ninguna compensación al cliente. Todo ello debido, seguramente, a la falta de flexibilidad en sus procesos de negocio.


Llegados a este punto la compañía debería plantearse serios cambios en su CRM. Por una serie de errores de libro, ha perdido a un cliente, es más ha ganado una prescripción negativa muy importante. En este caso se presentan, por lo menos, tres de los grandes errores que cometen las compañías en sus estrategias CRM. Primero, no han sabido manejar la incidencia provocada por su propio servicio y solucionar el problema del cliente de forma adecuada, a pesar de haberse dado cuenta de la situación no ha dado prioridad al alta para solucionar el problema. Segundo, el operador que lo atendió no escucho al cliente, en vez de hacer un cambio tramitó un nuevo alta, seguramente presionado por mejorar sus estadísticas comerciales. Tercero, la empresa no ha sabido establecer un mecanismo de retención de clientes, y no me refiero a poner trabas para darse de baja, sino a hablar con el cliente para conocer los motivos de su baja y en caso de ser posible tratar de evitar la pérdida.


Espero que esta reflexión sobre errores de CRM os sirva de algo. En este mundo, muchas veces se aprende más de los errores que de los aciertos. Además, viendo estos errores, seguro que a la mayoría se os ocurren soluciones a los mismos con Microsoft Dynamics CRM ¿verdad?


Un saludo,


Marco Amoedo Martínez

Modificación masiva de registros sin programar

Ayer, leyendo el blog del equipo de Microsoft Dynamics CRM, encontré un post sobre la poco conocida capacidad que tiene el CRM para permitir modificar varios registros a la vez. La verdad, es que para mi esta capacidad era una total desconocida, y eso que en más de una ocasión la he echado de menos.


La causa del desconocimiento de esta funcionalidad puede estar provocada por su “ocultación” y la confusión a la que da lugar su nombre. Para acceder a ella tenemos que seleccionar editar, en el menú “más acciones” de la vista de grid de la entidad que queramos editar. Como veis no es que este muy a la vista, ni tampoco que su nombre permita entrever la capacidad de edición múltiple que tiene. De hecho, en el propio Blog del equipo del CRM le achacan la falta de conocimiento de esta funcionalidad a esto.


Para utilizarla tenemos que seleccionar el conjunto de registros sobre los que vamos a realizar la modificación, y luego pulsar la opción editar en el menú “más acciones”.



Esta funcionalidad se encuentra disponible para varias entidades del CRM, como casos, cuentas, contactos, oportunidad, productos, listas de marketing, clientes potenciales…). Cuando accedamos a esta opción nos aparecerá un formulario de edición del tipo de la entidad seleccionada con todos los campos en blanco, en este formulario modificaremos sólo aquellos campos que deseemos editar en conjunto para todos los registros, los que queden en blanco no sufrirán modificación ninguna. Además, al acceder a este formulario veremos cómo hay campos inhabilitados y sobre los que no podremos hacer una edición múltiple, como por ejemplo el propietario en los contactos.



¿Cuándo puede ser útil? Pues muy fácil, imaginad que una empresa cliente cambia su ubicación o su teléfono y tenemos que modificar esos datos en todos los contactos de esa cuenta. Vamos a la vista de contactos, hacemos una búsqueda avanzada para filtrar los contactos de esa cuenta, los seleccionamos todos y utilizamos la edición múltiple para modificar los datos de ubicación y teléfono.


¿Os habéis encontrado alguna vez con la necesidad de editar múltiples registros?¿Ya conocías esta funcionalidad? ¿Nos sorprenderá el equipo del CRM con más funcionalidades ocultas?


Un Saludo,


Marco Amoedo Martínez

Crear Consultas FetchXML de forma Sencilla – FetchXMLBuilder

En el último post hablábamos sobre las formas de recuperar colecciones de objetos de Microsoft Dynamics CRM a través de peticiones a los métodos RetrieveMultiple y Fetch de los servicios web, y veíamos las diferencias entre ambos. Veíamos también, como Fetch utilizaba un lenguaje de consulta llamado FetchXML, que puede resultar un poco “complejo”. Pero gracias de nuevo a la gran comunidad que existe sobre esta solución CRM, nos encontramos con una herramienta que nos facilitará muchísimo la vida a la hora de crear y evaluar consultas FetchXML.


La herramienta gratuita de la empresa Tekatur se llama FetchXML Builder, en el enlace a su web encontrareís la herramienta para descarga así como la documentación de la misma. Esta utilidad nos permitirá crear y probar sentencias FetchXML de forma sencilla y rápida, adaptándose además a nuestra implementación de CRM ya que lo primero que hace la aplicación al iniciarse es recuperar la lista de metadatos de nuestro servidor CRM.



Una vez obtenidos los metadatos de nuestra instalación de Microsoft Dynamics CRM, nos aparecerá la siguiente pantalla donde tendremos las principales opciones para crear una nueva consulta y probarla. Como podéis ver, podemos seleccionar la entidad principal de la consulta, los campos que queremos incluir, la ordenación, filtrado y los joins con otras entidades.



Si pulsamos sobre añadir un nuevo Link aparecerá el formulario para editar enlaces. Este formulario, nos permitirá seleccionar la relación sobre la que haremos el join (o especificarla manualmente), seleccionar los filtros sobre la relación, y seleccionar los campos de la entidad relacionada que queremos incluir en los resultados. Esta última posibilidad, incluir campos de otras entidades en los resultados, es una de las diferencias entre usar Fetch o RetrieveMultiple. Además también tenemos la posibilidad de establecer el tipo de join (natural,inner y outer), la ordenación, y el alias de la relación que se mostrará en los resultados. A continuación podéis ver este formulario de edición de links.



Finalmente, tenemos los formularios para editar filtros y condiciones de los filtros, que nos permiten establecer filtrados tanto para la propia entidad como para los links con otras entidades.




Como veis, esta es una magnífica herramienta que nos puede ayudar en más de una ocasión con el lenguaje FetchXML, y sobre todo, que nos puede servir de muchísima ayuda para comprender mejor este potente de lenguaje de consulta de Microsoft Dynamics CRM.


Sólo tengo una pega, la edición de filtros no permite anidarlos, con lo que perdemos posibilidades a la hora de crear filtros. Es decir, no es posible crear un filtro tipo (cond1 or (cond2 and cond3)) con esta herramienta, algo que si está soportado por el lenguaje FetchXML. De todas formas hay un rodeo sencillo para conseguirlo, que es crear los filtros por separado, sin anidamiento, y luego modificar la consulta FetchXML que genera para anidarlos nosotros. Por ejemplo encerrando los filtros en un nuevo filtro <filter type=’or’> …. <filter>


¿Qué os parece la herramienta? ¿Creéis que es útil el lenguaje FetchXML?


Saludos,


Marco Amoedo Martínez

Descargar FetchXML Query Builder

Recuperar colecciones con los Servicios Web – RetrieveMultiple y Fetch

La última vez que hablamos sobre los métodos de los servicios web del CRM dejamos a un lado dos métodos que nos permiten recuperar colecciones de entidades, los métodos RetrieveMultiple() y Fetch(). Como vamos a ver, los dos nos permiten recuperar colecciones de objetos de Microsoft Dynamics CRM, aunque con unos matices y filosofía de utilización muy distintos.


RetrieveMultiple


El método RetrieveMultiple es un método “fuertemente tipado” que nos permite recuperar una colección de registros de una sola entidad del CRM, es decir nos permite recuperar una colección de objetos del mismo tipo. Esta es una de las grandes diferencias con Fetch, ya que el lenguaje de consulta FetchXML utilizado por el método Fetch no es fuertemente tipado con lo que podemos recuperar atributos de distintos tipos de entidad al igual que hacemos en sentencias SQL. Por poner un ejemplo, si queremos recuperar varias columnas de la entidad contactos y el nombre de la cuenta a la que pertenecen en una sola consulta tendremos que usar FectchXML, ya que con RetrieveMultiple solo podemos recuperar columnas de una entidad con lo que no podríamos incluir el nombre de la cuenta.


La otra característica distintiva de este método es que nos permite construir las consultas de manera programática, utilizando objetos QueryExpression o QueryByAttribute. ¿Cuándo utilizamos uno u otro? Pues la respuesta es más o menos sencilla. Si lo que necesitamos es recuperar un conjunto de registros de una entidad en los que un conjunto de atributos tome un determinado valor, utilizaremos QueryByAttribute. Como por ejemplo, recuperar todas las cuentas cuya ciudad sea Madrid y su país España.











// Create the QueryByAttribute object.


QueryByAttribute query = new QueryByAttribute();


query.ColumnSet = new AllColumns();


query.EntityName = EntityName.account.ToString();


 


// The query returns all accounts where address1_city is Madrid


// and address1_country is España.


query.Attributes = new string [] {«address1_city», «address1_country»};


query.Values = new string [] {«Madrid», «España»};


 


Si necesitamos condiciones más complejas tendremos que usar un objeto del tipo QueryExpression. Este tipo de objetos de consulta dispone de una propiedad Criteria, que nos permite utilizar objetos FilterExpression para crear condiciones de filtrado más complejas. Y de la propiedad LinkEntities que nos permite establecer filtros con Joins sobre otras entidades. Por ejemplo, podemos crear una consulta con la que obtener el nombre y el identificador de las cuentas cuyo dueño no tenga como apellido Amoedo.









 


// Return Accounts whose owner’s last name is not Amoedo


// Create a column set that holds the names of the columns to be retrieved.


ColumnSet cols = new ColumnSet();


 


// Attributes that we want to retrieve.


cols.Attributes = new string [] {«name», «accountid»};


 


// Create the condition expression.


ConditionExpression condition = new ConditionExpression();


 


// Set the condition for the retrieval to be when the last name of the account’s owner is not Amoedo.


condition.AttributeName = «lastname»;


condition.Operator = ConditionOperator.NotEqual;


condition.Values = new string [] {«Amoedo»};


 


// Build the filter based on the condition.


FilterExpression filter = new FilterExpression();


filter.FilterOperator = LogicalOperator.And;


filter.Conditions = new ConditionExpression[] {condition};


 


// Create a LinkEntity to link the owner’s information to the account.


LinkEntity link = new LinkEntity();


 


// Set the properties of the LinkEntity.


link.LinkCriteria = filter;


 


// Set the linking entity to be the account and set the linking attribute to be the owninguser.


link.LinkFromEntityName = EntityName.account.ToString();


link.LinkFromAttributeName = «owninguser»;


 


// Set the attribute and entity being linked to.


link.LinkToAttributeName = «systemuserid»;


link.LinkToEntityName = EntityName.systemuser.ToString();


 


// Create the query.


QueryExpression query = new QueryExpression();


 


// Set the properties of the query.


query.EntityName = EntityName.account.ToString();


query.ColumnSet = cols;


query.LinkEntities = new LinkEntity[] {link};


 


Sobre QueryExpression y QueryByAttribute hay que comentar un par de cosillas más. Como la existencia en ambos tipos de objeto de la propiedad PageInfo, que permite recuperar los resultados página a página según el tamaño de página que indiquemos. Y también, la posibilidad de utilizar el método Execute para realizar consultas mediante el mensaje RetrieveMultipleRequest.


 


Fecth


Este método, al contrario que RetrieveMultiple, no utiliza tipado “fuerte” para consultar datos. En vez de utilizar objetos para construir las consultas, utilizamos un lenguaje de consulta llamado FetchXML, y en vez de obtener una BusinessEntity Collection como resultado, obtenemos un documento XML. Con esto conseguimos una mayor flexibilidad, a cambio de una mayor “complejidad” a la hora de crear las consultas. Digo mayor complejidad, porque normalmente es más sencillo construir una consultar mediante objetos query que mediante FetchXML, y por que puede resultar más cómodo obtener los resultados como una colección de objetos que como un documento XML.


Sin embargo, gracias a la ausencia de tipado fuerte, tenemos algunas ventajas como el poder recuperar columnas de más de una entidad. Es decir, el resultado de la consulta puede mezclar datos de varias entidades, cosa que no se puede hacer con RetrievMultiple. Vamos, que tenemos las mismas posibilidades para hacer joins que en SQL.


Por ejemplo, veamos como quedaría la consulta que anteriormente hacíamos con una QueryExpression utilizando FetchXML.









// Retrieve all accounts where the last name is not Amoedo.


string fetch2 = @»


<fetch mapping=’logical’>


<entity name=’account’>


<attribute name=’accountid’/>


<attribute name=’name’/>


<link-entity name=’systemuser’ to=’owninguser’>


<filter type=’and’>


<condition attribute=’lastname’ operator=’ne’ value=’Amoedo’ />


</filter>


</link-entity>


</entity>


</fetch>


«;


 


// Fetch the results.


String result2 = service.Fetch(fetch2);


 


Evidentemente, el código es menos extenso, pero como veis ahora la consulta no es más que un string con XML, con lo que perdemos las comprobaciones en tiempo de compilación propias del tipado fuerte. Además, los resultados también son un string con XML, con lo que para manejarlos tendremos que incluir más lógica.


Otra cosa muy interesante de FetchXML, que ya comentamos en el artículo sobre RSS, es que Microsoft Dynamics CRM almacena todas las consultas avanzadas y las consultas de las vistas del sistema como FetchXML, y como estas consultas son accesibles a través de los servicios web (entidad savedquery) tenemos un montón de ejemplos de consultas incluidas de serie en nuestro sistema.


Destacar también, que al igual que con los objetos Query, con FetchXML también es posible utilizar paginado.


RetrieveMultiple vs Fecth


Bueno, y después de todos esto ¿Cual usamos? Pues como buen gallego que soy ya sabéis la respuesta… Depende.


Vamos a repasar las principales diferencias primero entre ambos métodos:






















RetrieveMultiple


Fetch


Valores de retorno “fuertemente tipado”


Valores de retorno NO fuertemente tipados


Consultas construidas con objetos tipo Query


Consultas construidas con FecthXML


Centrado en Business Entities, devuelve valores de una única entidad


Business Entities agnóstico, puede devolver valores procedentes de atributos de varias entidades


Soporta Join (pero solo para filtrado)


Soporta Join


 


A la vista de las diferencias, la idea queda más o menos clara. Debemos tratar de utilizar RetrieveMultiple cuando queramos obtener resultados de fuertemente tipados, de una única entidad, y queramos realizar alguna operación sobre los objetos de negocio obtenidos, por ejemplo, recuperar las cuentas de una ciudad para asignárselas a un determinado comercial mediante los servicios web.


Sin embargo, Fetch será adecuado cuando necesitemos realizar alguna consulta para obtener una combinación de datos de varias entidades, cuando queramos guardar la consulta en un fichero de manera sencilla, cuando no necesitemos resultados fuertemente tipados, o incluso cuando obtener los resultados en XML sea una “obligación” para poder interoperar con otro sistema. Por poner un ejemplo de uso de Fetch, imaginad que disponemos de un servicio web que proporciona información sobre los productos en oferta a nuestros mayoristas, aquí podríamos utilizar un servicio web que utilice una consulta FetchXML, almacenada en un fichero XML, para obtener un documento XML para enviar como resultado a través del Servicio Web.


Compatibilidad de FetchXML y los objetos Query


Finalmente, decir que existe la posibilidad de hacer conversiones entre ambos formatos. Para ello, disponemos de los mensajes FetchXmlToQueryExpressionRequest y QueryExpressionToFetchXmlRequest, que utilizados con el método Excute de los servicios web nos permitirán convertir de un formato a otro. Aunque hay que tener cuidado, ya que la conversión no siempre es directa.


Para terminar


Existen trucos para construir consultas en FetchXML, como utilizar el editor de consultas avanzadas del propio Microsoft CRM, guardar la consulta, y luego recuperar el FetchXML a través de los servicios web o de las vistas Filtradas. Pero, no os preocupéis, próximamente veremos que existen herramientas para crear consultas FecthXML de manera sencilla.


Para obtener más información sobre todo esto, os recomiendo que echéis un vistazo al SDK. En especial a la sección Building Queries del apartado de desarrollo con los Servicios Web de Microsoft CRM.


Bueno, espero que este “rollo” haya sido de utilidad para alguien. Dejad los comentarios, dudas, sugerencias, quejas y demás que queráis.


Un Saludo,


Marco Amoedo Martínez