viernes, 28 de septiembre de 2012

FetchXml Error CRM 2011: “Number of link entities in query exceeded maximum limit”

En CRM una de las formas de hacer consultas a través de los web services es a través de los famosos “FetchXML”. ( ver sdk: http://msdn.microsoft.com/en-us/library/gg328117.aspx)
De esta forma y con un lenguaje basado en formato XML, podemos hacer consultas de forma bastante sencilla, incluso se permite hacer “joins” mediante los “link-entity” ademas de otras funcionalidades (ver el esquema de los “FetchXml” aquí: http://msdn.microsoft.com/en-us/library/gg309405.aspx).
Bien, aquí hay un ejemplo de un XML con una “linked-entity” (Join):
   1: <fetch mapping='logical'>

   2:    <entity name='account'>

   3:       <attribute name='accountid'/>

   4:       <attribute name='name'/> 

   5:       <link-entity name='systemuser' to='owninguser'> 

   6:          <filter type='and'> 

   7:             <condition attribute='lastname' operator='ne' value='Cannon' /> 

   8:           </filter> 

   9:       </link-entity> 

  10:    </entity> 

  11: </fetch> 

 
El problema es que la vida a veces nos lleva a realizar consultas mas grandes, con muchas entidades relacionadas.

En caso de hacer una consulta muy grande en cuanto a linked-entities, hay que tener en cuenta que hay un máximo definido que es de 10. Si nos pasamos de esto, nos puede aparecer un error como el siguiente:


   1: <error> 

   2:   <code>0x8004430d</code> 

   3:   <description>Number of link entities in query exceeded maximum limit.</description> 

   4:   <type>Platform</type> 

   5: </error>

 
Ante esto, hay una solución no soportada, que pasa por crear un registro nuevo en la base de datos de configuración del CRM (MSCRM_CONFIG). El registro es un parámetro con el nombre “QueryLinkEntityLimit”. En el siguiente ejemplo lo amplío a “20”.


   1: INSERT INTO DeploymentProperties(Id,ColumnName,IntColumn,Encrypted)

   2: VALUES('6C3BE16F-943B-E111-9AE4-00155D010A39','QueryLinkEntityLimit',20,0)

   3:  

   4: select * from DeploymentProperties where ColumnName='QueryLinkEntityLimit'
 

En primer valor en el campo “Id", se debe introducir el mismo Id que el resto de registros.

Espero les sirva. tener en cuenta que esto es una solución no soportada, y que solo funciona en entornos OnPremise.


Saludo!

jueves, 27 de septiembre de 2012

Authenticación en plugins y diferencias entre 4.0 y 2011

Hola,  como muchos habrán utilizado alguna vez, al trabajar con Plugins, a veces es difícil saber con que usuario se realizan las acciones que se desarrollen en el mismo.

Primero hay que tener en cuenta en el registro de los Plugins, en donde se puede seleccionar que dicho paso se ejecute con un usuario específico, o por el contrario el “Calling User”, que permitirá que en el contexto se “pase” el id del usuario que ha lanzado el Plugin:

image

Una vez que estamos en el código, debemos conectarnos al CRM para realizar diferentes acciones como por ejemplo una consulta, una actualización, etc.

Para esto se utiliza en 2011 el método IOrganizationServiceFactory.CreateOrganizationService (http://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.iorganizationservicefactory.createorganizationservice.aspx).

En CRM 4.0 se utilizaba el método IPluginExecutionContext.CreateCrmService (http://msdn.microsoft.com/en-us/library/bb959583.aspx).

Para saber como podemos autenticarnos en los plugins dejo un listado que además muestra las diferencias entre 4.0 y 2011:

Tipo CRM 4.0 CRM 2011
Usuario conectado (Calling User) ICrmService service = context.CreateCrmService(true);
IOrganizationService service = serviceFactory.CreateOrganizationService(Guid.Empty);
Un usuario específico ICrmService service = context.CreateCrmService(context.UserId); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
System User ICrmService service = context.CreateCrmService(false); IOrganizationService service = serviceFactory.CreateOrganizationService(null);

Un saludo,