Vamos ver aqui como se realiza um CRUD (Create, Retrieve, Update e Delete) no Microsoft Dynamics CRM 4.0, mas antes, vamos falar um pouco sobre a Plataforma Dynamics CRM 4.0. Como o nome do produto mesmo diz, o Dynamics CRM 4.0 é a última versão do Sistema de Relacionamento com o Cliente da Microsoft. Atualmente está disponível o Rollup 6 para correções de problemas na aplicação.
Totalmente desenvolvido em .NET C#, o CRM é muito mais do que um simples sistema de Relacionamento com o Cliente, ele também é uma plataforma altamente customizável, tanto a nível de tela (com alguns cliques é possível tanto criar entidades como campos) como a nível de customização de código. Como outros produtos Microsoft, o CRM possui uma série de Web services que permitem sua integração via código com outras aplicações e é nisto que se baseia este artigo.
Para começar vamos criar um novo projeto no Visual Studio 2008, um Console Application com o nome CRM – Contatos:

Agora com nossa aplicação criada, vamos adicionar uma referência web ao CRM e para isto vamos ao Solution Explorer, no botão direito em cima do nome do projeto e clique em Add Service Reference > Advanced > Add Web Reference >. Na tela que se abriu no campo URL, vamos digitar o endereço do Web Service. O CRM disponibiliza dois webservices:
- CrmService: interface de acesso aos dados contidos no CRM e é com ele que vamos trabalhar.
- MetaDataService: interface para trabalhar com os metadados do CRM, ou seja, entidades, campos, regras, etc.
Normalmente, o endereço dos webservices do CRM é http:/// mscrmservices/2007/.

No Web reference name digite CRMSDK e clique em Add Reference:

Para começar, vamos colocar o namespace do CrmSdk na nossa aplicação e para isto basta digitarmos Using CrmSdk na parte superior do nosso código:

A classe CrmService é a responsável pela comunicação da nossa aplicação com os dados internos do nosso CRM. Vamos instanciar a nossa classe para realizar a nossa conexão com o CRM da nossa empresa. Para isto precisamos informar o nosso login, URL do webservice e um detalhe a mais que não existia em versões anteriores: o CRMAuthenticationToken. Ele informa qual a forma de login da nossa aplicação e também a qual empresa estamos tentando conectar, já que agora o CRM 4.0 Enterprise pode disponibilizar várias empresas (também visto como instâncias nomeadas):
private CrmService crm;public CrmService CRM
{
get
{
if (crm == null)
{
crm = new CrmService();
//Autenticação passando Login e Senha
crm.Credentials = new System.Net.NetworkCredential
("Administrator","qwer1234", "Dominio");
//URL do WebService
crm.Url = "http://endereco:5555/mscrmservices/2007/CrmService.asmx";
//Instanciar a classe CrmAuthenticationToken
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0;//Autenticação via AD
/*Nome da Organização ao qual vamos conectar
* Em caso de dúvida, o nome fica em frente a url de acesso ao CRM
* Por exemplo: http://endereco:5555/ORGANIZACAO */
token.OrganizationName = "Organizacao";
crm.CrmAuthenticationTokenValue = token;
return crm;
}
else
return crm;
}
}
Agora vamos criar um contanto na entidade Contato do nosso CRM. A forma de inserção é sempre a mesma, só muda o nome da entidade que vamos instanciar.
Como o CRMService nos proporciona um acesso altamente tipado as nossas entidades, é bastante simples trabalharmos com os dados que elas contêm ou conterão. Por exemplo, se queremos criar um contato basta instanciarmos a classe contato e preenchermos as devidas propriedades da classe, conforme o exemplo abaixo:
public void CriaContato()
{
//Cria uma instancia da classe Contact
contact contato = new contact();
contato.firstname = "Olavo";
contato.lastname = "Neto";
this.CRM.Create(contato);
}
Após a execução do nosso novo método, se tudo ocorrer bem, poderemos ver dentro do CRM, na devida entidade, o nosso novo contato com os dados preenchidos:

Capturando um dado no CRM
Bom, agora que já criamos um contato, vamos ver como capturá-lo. Como eu falei no tópico anterior, existem várias maneiras de se fazer algo no CRM, mas vou listar aqui o que considero as duas principais maneiras de capturar um dado dentro do CRM:
- Capturar uma coleção de dados dentro do CRM;
- Capturar um dado específico.
Capturar uma coleção de dados dentro do CRM
Retornar uma coleção de dados de dentro do CRM é bem parecido com executar uma QUERY dentro do SQL Server. De certa forma, o que vamos fazer é montar uma query através de um conjunto de classe e métodos do SDK.
public List<contact> CapturaContatos{
List<contact> contatos = new List<contact>();
Como toda query em SQL, devemos iniciar informando às colunas que queremos obter na nossa consulta, em SQL utilizamos o SELECT. No CRM utilizamos o ColumnSet:
ColumnSet columns = new ColumnSet();
columns.Attributes = new string[] { "contactid", "fullname" };
Caso queria-se obter todas as colunas de uma única vez (SELECT * FROM) pode-se utilizar a classe AllColumns:
AllColumns columns = new AllColumns();
Vamos agora continuar nossa query com as restrições. Como no SQL, não é obrigatório o uso das restrições caso se deseje obter todos os dados das entidades.
A restrições do CRM se baseiam em duas classes, a primeira é a ConditionExpression aonde informamos o nome do campo que queremos pesquisar o operador da busca (Equal, Like, etc.) e o valor a ser pesquisado.
A segunda classe é a FilterExpression onde informaremos todas as condições já criadas e o operador entre elas (AND ou OR):
ConditionExpressionconditionNome =newConditionExpression();
conditionNome.AttributeName ="firstname";
conditionNome.Operator =ConditionOperator.Equal;
conditionNome.Values =newobject[] {"Olavo"};
FilterExpressionfilter =newFilterExpression();
filter.Conditions =newConditionExpression[] { conditionNome };
Agora, vamos ordenar nossa busca através da classe OrderExpression:
OrderExpressionorder =newOrderExpression();
order.AttributeName ="fullname";
order.OrderType =OrderType.Ascending;
Para finalizar, vamos juntar tudo no QueryExpression, classe principal da nossa busca, aonde informamos as colunas, os filtros, a entidade que iremos realizar a busca e os ordenadores.
QueryExpression query = new QueryExpression();
query.ColumnSet = columns;
query.Criteria = filter;
query.EntityName = EntityName.contact.ToString();
query.Orders = new OrderExpression[] { order };
Realizando a consulta através do método RetrieveMultiple que retorna uma BusinessEntityCollection (coleção de entidades):
BusinessEntityCollection bu = this.CRM.RetrieveMultiple(query);
foreach (BusinessEntity b in bu.BusinessEntities)
{
contact contato = (contact)b;
contatos.Add(contato);
Console.Write("Anote este ID:" + contato.contactid.Value);
Console.ReadLine();
}
return contatos;
}
Execute o método, copie o ID que apareceu, ele será importante para o próximo exemplo:

Capturar um dado específico
Já vimos como realizar uma consulta completa no Dynamics CRM, agora vamos ver como criar uma busca direta pelo ID da entidade, para isto basta termos o Guid identificador da entidade e informamos as colunas que desejamos obter.
Para nosso exemplo, usei o AllColumns para retornar todas as colunas da entidade Contato.
A consulta é feita através do método Retrieve que retorna uma BusinessEntity:
public contact CapturaContato()
{
AllColumns columns = new AllColumns();
return ((contact)this.CRM.Retrieve(EntityName.contact.ToString(),
new Guid("e2850cd6-9cb6-dd11-b305-0014d11389c6"), columns));
}
Atualizando um Dado no CRM
Atualização é extremamente parecido com a inserção de dados. A única diferença é que se faz necessário informar a chave do registro que será modificado e em vez do método Create, utilizaremos o Update.
public void AtualizaContato()
{
contact contato = new contact();
contato.contactid = new Key();
contato.contactid.Value = new Guid("e2850cd6-9cb6-dd11-b305-0014d11389c6");
contato.emailaddress1 = "luke_neto@hotmail.com";
this.CRM.Update(contato);
}
Veja o resultado dentro do CRM:

Deletando um Dado no CRM
Deleção de dados é quase sempre o mais simples a ser feito, no CRM não é diferente. Para isto, basta chamarmos o método Delete e passar como parâmetro o nome da entidade que iremos deletar e a chave do registro:
public void DeletaContato()
{
this.CRM.Delete(EntityName.contact.ToString(),
new Guid("e2850cd6-9cb6-dd11-b305-0014d11389c6"));
}
Dicas
Algumas dicas que eu considero serem de ajuda para quem for trabalhar com o SDK do CRM:
- Também é possível realizar todos os procedimentos aqui mostrados, inclusive retornar os dados em XML, usando o método Fetch da classe CrmService.
- Quando for digitar o nome das colunas a serem capturadas no ColumnSet, nunca digite o nome delas ou coloque qualquer letra em MAIÚSCULO;
- A melhor maneira de verificar o que aconteceu de errado na sua aplicação é através do SoapExcepetion:
catch(System.Web.Services.Protocols.SoapExceptionsoapEx) { throw newSystem.Web.Services.Protocols.SoapException (soapEx.Detail.InnerText,soapEx.Code); }
- Não é possível trabalhar com entidades associativas (entidades intermediárias de relacionamento N:N) diretamente, somente através do Fecth;
- Não se preocupe com os dados a serem retornados a nível de permissão, pois o CRM só traz os dados que aquele usuário logado tem permissão para ver;
- Existe um bug no CRM 4 no qual não é possível retornar as colunas StatusCode e StateCode de nenhuma entidade. Este problema foi resolvido no RollUp 2;
- Tente não usar o AllColumns, pois ele é tão prejudicial como o Select * From.