Business - CRM

Trabalhando com Relacionamentos N:N no Microsoft Dynamics CRM 4.0

Este artigo demonstra como se trabalha via CRM SDk com entidades que possuem relacionamento N:N (Many to Many).

por Olavo Oliveira Neto



Umas das novidades mais legais do Microsoft Dynamics CRM 4.0 é a possibilidade de criar relacionamento N:N (Many to Many) entre as entidades, este tipo de relacionamento me possibilita por exemplo dizer que um contato contem vários contatos e que vários contatos participam de vários contratos diferentes.

Claro que, para quem conhece, não existe relacionamento N:N dentro do banco de dados, ou é N:1 ou 1:N, então como isto é possível....a resposta é tão simples, ao solicitarmos a criação de um relacionamento do tipo Many to Many entre duas entidades, o CRM, de forma implícita, cria uma tabela intermediaria no banco de dados que contem apenas 4 atributos sendo dois deles as chaves primarias das entidades relacionadas

image_thumb[4]%20043383E0.png


Abstraindo todas as colunas das entidades laterais, a figura acima mostra a tabela de referencia para o relacionamento N:N.

Legal, vamos para o divertido, como trabalhar com está novidade via SDK...primeiro vem a noticia chata, as tabelas intermediarias não são visualizadas como entidades então não podemos trabalhar com o Retrieve nem com o RetrieveMultiple para poder Capturar os dados, o mesmo vale para a gravação de dados, não podemos usar os métodos comuns para este procedimento, porem não é difícil realizar tais operações.

1. Criando Dados em entidades N:N
O processo de gravação é bem simples, para isto contamos com a classe
AssociateEntitiesRequest que junto com a classe Moniker serão os responsáveis por gravar os dados no nosso BD.

    1. Para iniciar, deve-se adicionar a Referencia ao endereço http://ENDEREÇO_crm/mscrmservices/2007/CrmService.asmx sob o nome de CrmSdk.
    2. No topo da classe, vamos instanciar as bibliotecas do CRM através do comando using CrmSdk;

Vamos criar uma classe void responsável apenas por salvar os Contatos que fazem relacionamento com os contratos
public void SalvaContato_Contrato()

        {

            //Instância uma nova conexão ao CRM

            CrmService service = new CrmService();

            service.PreAuthenticate = true;

            //Instância o Token de autenticação

            CrmAuthenticationToken Token = new CrmAuthenticationToken();

            Token.AuthenticationType = 0;//0 = Autenticação por AD

            Token.OrganizationName = "Olavo";//Nome da Organização ao qual vamos nos conectar

            service.CrmAuthenticationTokenValue = Token;

            //Informa usuário que está conectando

            service.Credentials = new System.Net.NetworkCredential("Olavo", "----------------", "CRM4");

           

            //Inicia o Request

            AssociateEntitiesRequest associateRequest = new AssociateEntitiesRequest();

            //Moniker 1 será responsavel pelos dados da entidade Contact

            associateRequest.Moniker1 = new Moniker();

            associateRequest.Moniker1.Id = new Guid("cd06d480-40b9-de11-a3af-00155d013108");

            associateRequest.Moniker1.Name = EntityName.contact.ToString();

            //Moniker 2 será responsavel pelos dados da entidade Contract

            associateRequest.Moniker2 = new Moniker();

            associateRequest.Moniker2.Id = new Guid("EC1864D0-40B9-DE11-A3AF-00155D013108");

            associateRequest.Moniker2.Name = EntityName.contract.ToString();

            //Informa o nome do relacionamento

            associateRequest.RelationshipName = "servicecontractcontacts_association";

            AssociateEntitiesResponse response = (AssociateEntitiesResponse)service.Execute(associateRequest);

}

2. Capturando Dados da tabela de interseção

Capturar os dados contidos nas tabelas de interseção (intermediarias) é um processo simples, porém bem diferente do usual Retrieve e do RetrieveMultiple. Por se tratar de tabelas de interseção e não de entidades propriamente ditas, o CRM não consegue realizar consultas diretas dentro dela, tanto que se você tentar pesquisar o nome da tabela através do Enum EntityName, verá que não consta o nome da tabela de interseção.

A partir de agora, para realizarmos este tipo de consulta, teremos de usar o método Fetch da classe CrmService trabalha com consulta em XML e que retorna o resultado também em XML.

O xml de consulta é bem simples, segue o modelo:
<fetch mapping="logical">
         <entity name="servicecontractcontacts">
            <all-attributes/>
               <filter>
                  <condition attribute="contractid" operator="eq"                  value="EC1864D0-40B9-DE11-A3AF-00155D013108" />
               </filter>
          </entity>
       </fetch>

O código para realizar a consulta fica mais ou menos assim:

public Guid RetornaUsuario_Contrato()

{

            //Instância uma nova conexão ao CRM

            CrmService service = new CrmService();

            service.PreAuthenticate = true;

            //Instância o Token de autenticação

            CrmAuthenticationToken Token = new CrmAuthenticationToken();

            Token.AuthenticationType = 0;//0 = Autenticação por AD

            Token.OrganizationName = "Olavo";//Nome da Organização ao qual vamos nos conectar

            service.CrmAuthenticationTokenValue = Token;

            //Informa usuário que está conectando

            service.Credentials = new System.Net.NetworkCredential("Olavo", "----------------", "CRM4");

            //Monta o XML de consulta

            //Entity name = <Informa o Nome da tabela de interseção>

            //Caso se queria utilizar mais de um Condition, deve-se acrescentar no filter type = "and">

            string Consulta =

            @"<fetch mapping="logical">

                <entity name="servicecontractcontacts">

                    <all-attributes/>

                        <filter>

                            <condition attribute="contractid" operator="eq"

                            value="EC1864D0-40B9-DE11-A3AF-00155D013108" />

                        </filter>

                </entity>

             </fetch>";

            //Captura resultado

            string Resultado = service.Fetch(Consulta);

            //Trabalhando com o XML retornado

            System.Xml.XmlDocument Document = new System.Xml.XmlDocument();

            Document.LoadXml(Resultado);

            System.Xml.XmlNodeList XmlNodes = Document.SelectNodes("resultset/result/contactid");

            if (XmlNodes.Count > 0)

                return new Guid(XmlNodes[0].InnerText);

            return Guid.Empty;

}

É isto pessoal. Nada de muito complicado, porem extremamente útil quando se tem entidades se relacionamento de N:N no Microsoft Dynamics CRM 4.0

Olavo Oliveira Neto

Olavo Oliveira Neto