Artigo


ADO .Net Data Services - 3ª Parte

5/4/2009

Olá pessoal, vamos dar continuidade em nossa série sobre ADO.Net Data Services (DS), tecnologia introduzida no .Net Framework 3.5 SP1.

Este é o terceiro artigo da série, caso você não tenha lido os primeiros artigos, segue os links:
Artigo I
Artigo II

Aqui vamos tratar da manipulação de dados de uma entidade que possui uma propriedade relacionada à outra entidade, seguindo nosso modelo de dados iremos considerar a entidade "Categorias" que contêm um relacionamento com "TipoCategoria".

Seguindo a mesma idéia (hi agora não tem acento , escreve-se "ideia"), do artigo anterior vamos criar um "Form" para trabalhar o cadastro de Categorias conforme figura abaixo.


Figura 1: Formulário de manutenção de "Categorias"

Como já vimos todas as configurações do ADO.Net Data Services, vamos diretamente ao código.

Vamos implementar as funcionalidades de nosso formulário, começaremos vendo como podemos consultar um objeto específico da classe "Categoria". Para isso vamos inserir o seguinte código no evento click do botão "Consultar" (não vamos nos preocupar com validações em nossos exemplos).

private void btnConsultar_Click(object sender, EventArgs e)
{
    //endereço do serviço
   
Uri enderecoServico = new Uri("http://localhost:3752/DSProdutos.svc");
    //Contexto do serviço que utilizamos para manipular os dados

    srDSProdutos.
DBProdutosEntities contexto;
    contexto =
new ClienteWindows.srDSProdutos.DBProdutosEntities(enderecoServico);

    //fazendo a consulta ao serviço através de LINQ
   
var cat = (from c in contexto.Categorias
                  
where c.ID == Convert.ToInt32(txtID.Text)
                       
select c).FirstOrDefault();

    
if (cat != null)
     {
        txtDescricao.Text = cat.Descricao;
        txtIDTipoCat.Text = cat.TipoCategoria.ID.ToString(); //AQUI VAI DAR ERRO!!!
        txtDescTipoCat.Text = cat.TipoCategoria.Descricao; //AQUI TAMBÉM (de propósito)
     }

     
else
           
txtDescricao.Text = "No encontrado.";
}

Note que inserimos um erro que ocorrerá somente em tempo de execução, isso foi proposital para incluirmos um novo elemento em nossos estudos. O DS trabalha com o conceito "lazy loading". Lazy Loading é o mecanismo utilizado pelos frameworks de persistência para carregar informações sobre demanda. Esse mecanismo torna as entidades mais leves, pois suas associações são carregadas apenas no momento em que o método que disponibiliza o dado associativo é chamado.

No DS isso pode ser facilmente notado quando fazemos a chamada através da URI em nosso navegador, por exemplo, vamos consultar a Categoria "2" através do navegador utilizando o endereço:

http://localhost:3752/DSProdutos.svc/Categorias(2)

Obtemos o seguinte resultado:


Figura 2: Consulta a Categoria ID=2

Podemos perceber no XML retornado que existe um elemento "link rel" indicando que existe um relacionamento com "TipoCategoria" no entanto não temos acesso ao objeto relacionado, pois não vem carregado. Para obter o que queremos precisamos utilizar o parâmetro "expand" alterando nossa URI conforme abaixo:

http://localhost:3752/DSProdutos.svc/Categorias(2)?$expand=TipoCategoria

Com isso obtemos o resultado abaixo:


Figura 3: Consulta a Categoria ID=2 utilizando "expand"

Para obter o mesmo resultado em nosso código para o botão consulta, precisamos fazer uma pequena modificação em nossa expressão LINQ, veja abaixo o que deve ser feito.

private void btnConsultar_Click(object sender, EventArgs e)
{
    //endereço do serviço
   
Uri enderecoServico = new Uri("http://localhost:3752/DSProdutos.svc");
    //Contexto do serviço que utilizamos para manipular os dados

    srDSProdutos.
DBProdutosEntities contexto;
    contexto =
new ClienteWindows.srDSProdutos.DBProdutosEntities(enderecoServico);

    //fazendo a consulta ao serviço através de LINQ

      //AQUI UTILIZAMOS Expand
    var cat = (from c in contexto.Categorias.Expand("TipoCategoria")
                  
where c.ID == Convert.ToInt32(txtID.Text)
                       
select c).FirstOrDefault();

     
if (cat != null)
      {
        txtDescricao.Text = cat.Descricao;
        //agora sim, teremos acesso ao objeto Tipo Categoria.
        txtIDTipoCat.Text = cat.TipoCategoria.ID.ToString();
        txtDescTipoCat.Text = cat.TipoCategoria.Descricao;
     }

     
else
           
txtDescricao.Text = "No encontrado.";
}

Veja o resultado que obtemos ao consultar a Categoria "2" em nosso projeto WindowsForms.


Figura 4: Consulta a Categoria ID=2 utilizando o método "Expand"

Agora vamos ao botão 'Salvar' que será utilizado para incluir e alterar. Veremos que durante os procedimentos teremos um novo método apresentado chamado "SetLink" que é responsável por linkar os dois objetos, persistindo no banco de dados a chave estrangeira TipoCategoriaId na tabela Categorias.

private void btnSalvar_Click(object sender, EventArgs e)
{
   
//setando a URI do serviço
   
Uri enderecoServico = new Uri("http://localhost:3752/DSProdutos.svc");
   
//contexto do servio
    srDSProdutos.DBProdutosEntities contexto;
    contexto =
new ClienteWindows.srDSProdutos.DBProdutosEntities (enderecoServico);
    contexto.MergeOption = System.Data.Services.Client.
MergeOption.AppendOnly;

   
//criando o objeto que ser persistido
    srDSProdutos.
Categorias cat = new ClienteWindows.srDSProdutos.Categorias();
    cat.Descricao = txtDescricao.Text;

    //devemos buscar o objeto de TipoCategoria
    //para associar a Categoria
    var tipo (from t in contexto.TipoCategoria
                
where t.ID == Convert.ToInt32(txtIDTipoCat.Text)
                
select t).FirstOrDefault();


    if (txtID.Text == "Novo") //no caso de um novo cadastro
    {
       
//adicionando o objeto no contexto
        contexto.AddToCategorias(cat);
        //aqui fazemos o link entre Categoria e Tipo Categoria
        contexto.SetLink(cat, "TipoCategoria", tipo);

       
//salvando as alterações do contexto
        contexto.SaveChanges();
       
//no caso de novo cadastro o DS nos retorno o objeto
        //com isso podemos identificar o ID gerado pois utilizamos
        //um campo Identity (gerado sequencialmente)

        txtID.Text = cat.ID.ToString();
    }
   
else //alteração
    {
        cat.ID =
Convert.ToInt32(txtID.Text);
       
//para o caso de alteração, devemos atachar o objeto no contexto
        contexto.AttachTo(
"Categorias", cat);
        contexto.UpdateObject(cat);
        //no caso de update o setlink vem após o UpdateObject
        contexto.SetLink(cat, "TipoCategoria", tipo);

        contexto.SaveChanges();
    }
}

Agora vamos ver o código para o botão 'Excluir'.

private void btnExcluir_Click(object sender, EventArgs e)
{
   
//setando a URI do serviço
   
Uri enderecoServico = new Uri("http://localhost:3752/DSProdutos.svc");
   
//contexto do serviço
    srDSProdutos.DBProdutosEntities contexto;
    contexto =
new ClienteWindows.srDSProdutos.DBProdutosEntities (enderecoServico);
    contexto.MergeOption = System.Data.Services.Client.
MergeOption.AppendOnly;

   
//criando o objeto que ser excluído
    srDSProdutos.Categorias cat =
new ClienteWindows.srDSProdutos.Categorias ();
    cat.Descricao = txtDescricao.Text;
 
    cat.ID =
Convert.ToInt32(txtID.Text);
   
//para o caso de exclusão, devemos atachar o objeto no contexto
    contexto.AttachTo(
"Categorias", cat);
    contexto.DeleteObject(cat);
    contexto.SaveChanges();
}

Conclusão: Neste artigo aprendemos como trabalhar com entidades relacionadas com outras entidades, criando os vínculos entre elas e também aprendemos sobre o conceito "lazy loading" utilizado no DS. Em nosso próximo artigo criaremos as funções para o cadastro de produtos e como podemos navegar entre as entidades relacionadas. Até mais.

 



Marcelo Paiva - marcelo.paiva@devgoias.net

Analista de Sistemas, com 16 anos de experiência em engenharia de software, MCP e IBM CLP. Possui conhecimentos em ferramentas de workflow, infra-estrutura de servidores e redes. Trabalha com o .Net desde a versão 1.0 e atualmente desenvolve projetos na Softprime Soluções, com o Framework 3.5 SP1 utilizando tecnologias ADO Data Services e Linq to Entities.
blog: marcelosoftprime.spaces.live.com



| | Mais


Comentários

Qual a sua opinião?
Faça o login no topo do site ou cadastre-se rapidamente.



2003-2009 DevGoiás.NET. Todos os direitos reservados.