Olá pessoal, vamos agora finalizar nossa série sobre ADO.Net Data Services (DS), tecnologia introduzida no .Net Framework 3.5 SP1.
Este é o quarto artigo da série, caso você não tenha lido os primeiros artigos, segue os links:
Artigo I
Artigo II
Artigo III
Neste artigo vamos trabalhar um pouco mais sobre o relacionamento das entidades vendo como podemos navegar entre elas.
Vamos inicialmente criar um Form para fazer a consulta de produtos de uma determinada categoria (fizemos a carga dos produtos através do banco de dados diretamente).

Figura 1: Formulário de lisgatem de produtos por categoria
Como já vimos todas as configurações do ADO.Net Data Services, vamos diretamente ao código.
Vamos implementar a funcionalidade que busca a lista de produtos de uma determinada categoria informada pelo usuário. Então teremos o seguinte código para o evento click do botão "Consultar".
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.Expand("Produtos")
where c.ID == Convert.ToInt32(txtIDCategoria.Text)
select c).FirstOrDefault();
//carregando a lista de produtos, que é uma coleção de objetos do tipo "Produtos"
foreach (var prod in cats.Produtos)
{
lstProdutos.Items.Add(prod.Descricao);
}
}
Então inserindo o ID "2" para categoria, obteremos o seguinte resultado:

Figura 2: Consulta a Categoria ID=2
Outro interessante recurso de aprender no DS é como fazer para navegar entre os objetos agregados no objeto obtido através de uma consulta, por exemplo: Um produto pertence a uma categoria que por sua vez pertence a um tipo de categoria, então podemos através de um determinado produto buscar também o tipo de categoria.
Para isso vamos criar um formulário para o cadastro de produtos, e vamos buscar todas as informações agregadas conforme o exemplo abaixo, onde vamos buscar os dados do produto de ID=1 apresentando sua categoria e o tipo da mesma.

Figura 3: Consulta do Produto ID=1
Segue abaixo o código do evento click do botão que demonstra como obtemos as informações desejadas.
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 temos a novidade, pois para carregar um objeto agregado ao outro
//basta voc indicar a propriedade que deseja carregar separando com "/"
var produto = (from p in contexto.Produtos.Expand("Categorias/TipoCategoria")
where p.ID == Convert.ToInt32(txtIDProduto.Text)
select p).FirstOrDefault();
txtDescricaoProduto.Text = produto.Descricao;
//as demais propriedades abaixo somente so carregadas
//devido ao uso do mtodo Expand
txtIDCategoria.Text = produto.Categorias.ID.ToString();
txtDescricaoCategoria.Text = produto.Categorias.Descricao;
txtIDTipoCategoria.Text = produto.Categorias.TipoCategoria.ID.ToString();
txtDescricaoTipoCategoria.Text = produto.Categorias.TipoCategoria.Descricao;
}
Bônus: Sabemos que o DS faz a exposição do nosso modelo de dados para ser consumido através do WCF no padrão REST, no entanto podemos ocasionalmente precisar de criar alguma funcionalidade no que exige um determinado processamento e retorne ao nosso "client" apenas aquilo que precisamos.
Com o DS isto é perfeitamente possível. Vamos demonstrar como criar um método que retorne a soma total dos preços dos produtos, apenas para terem uma idéia de como funciona.
Devemos criar o método em questão, no arquivo ".cs" do nosso serviço (.svc), veja abaixo como isto deve ser feito.
[SingleResult] //aqui indicamos que vamos retornar um resultado simples (uma só atributo)
[WebGet(ResponseFormat = WebMessageFormat.Xml)]
public decimal SomaPrecosProdutos()
{
try
{
//aqui buscamos a soma dos preços dos produtos
var soma = (from i in this.CurrentDataSource.Produtos
select i.Preco).Sum();
return soma.Value;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
O detalhe agora é como fazemos para em nosso "client" para chamar este método e obter o resultado desejado. Para isso vamos em nosso formulário de produtos criar evento de um botão para retornar o que desejamos.

Figura 4: Consulta a soma dos preços dos produtos.
Para obtermos o resultado acima implementamos o seguinte código do evento click do botão "Total Preços":
private void btnPrecos_Click(object sender, EventArgs e)
{
string uri = "http://localhost:3752/DSProdutos.svc" ;
Uri ctxuri = new Uri(uri);
srDSProdutos.DBProdutosObjects contexto;
contexto = new ClienteWindows.srDSProdutos.DBProdutosObjects(ctxuri);
//definimos aqui a URI para chamar o método que criamos
Uri queryuri = new Uri(uri + "/SomaPrecosProdutos");
//buscando a soma dos preços dos produtos
decimal totalPrecos = contexto.Execute<decimal>(queryuri).First();
lblPrecos.Text = totalPrecos.ToString();
}
Conclusão: Chegamos ao final de nossa série de artigos do Astoria, espero que tenha contribuído para acrescentar mais conhecimentos aos colegas. Podemos perceber que o Astoria é uma ferramenta poderosa para fazer o tratamento de dados utilizando de tecnologias mais atuals como WCF e o padrão REST. Até mais.