Acesso a dados com Linq
Click here to see the english version of this post
Olá a todos. Peço desculpas pelo tempo em que estive sem postar aqui no blog. Antes de chegar no assunto gostaria muito de mandar um obrigado especial a todos os visitantes do Estação ZN, que está crescendo em acessos cada vez mais. Nós nos sentimos muito orgulhosos e felizes de ver que este conteúdo que nós postamos aqui e que são freqüentemente retirados de conversas e problemas do dia-a-dia está chegando a todos que acessam nosso blog. Se o que é postado aqui consegue ajudar, fazer pensar, ou até mesmo distrair alguém nosso trabalho já valeu a pena.
Para compensar vou postar sobre um assunto que nos (eu e o Gerson) deixou boquiabertos: Linq - Uma nova tecnologia de acesso a dados presente no Visual Studio 2008 e na .Net 3.5.
Linq é sigla para Language-integrated query. Significa que é uma tecnologia (ou melhor, um conjunto delas) que adiciona recursos de consulta semelhantes às queries da linguagem SQL no nível da linguagem (compilador).
O que isso quer dizer? Que esta tecnologia nos permite (entre outras coisas) consultar dados em memória, arquivos XML e até de bancos de dados relacionais de forma declarativa (funcional), ao invés da maneira imperativa tradicional que usamos.
Linq veio também para diminuir uma coisa chamada "impedance mismatch", que representa a diferença entre o modelo de classes/objetos do software e os modelos de entidades/relacionamentos do banco e dos arquivos XML. Explicando um pouco melhor: Vamos partir do seguinte princício: Dados Relacionais <> XML <> Objetos. No software nós utilizamos o modelo POO, com herança, polimorfismo e por aí vai. Os dados que nossos aplicativos geralmente acessam estão representados em forma de tabelas em bancos de dados relacionais ou arquivos XML. Entre estes três mundos nós não temos praticamente nenhuma compatibilidade; até os tipos de dados são diferentes.
Hoje em dia, para trabalhar com estes dados em nossos aplicativos nós precisamos usar as APIs que as linguagens nos fornecem. Mas nós sempre precisamos escrever mais código que deveríamos, e o código que escrevemos para acessar estes dados não representa claramente o resultado que queremos. Isso se deve à maneira imperativa que as linguagens requerem para acesso aos dados.
Ah, Felipe..., ..., ... Ok. Vamos a um exemplo:
Queremos fazer um select no banco de dados. Há algumas pequenas diferenças entre linguagens, mas a idéia é a mesma:
Este modelo nos traz a necessidade de implementar, de forma imperativa, o que o sistema deve fazer em cada momento. Também precisamos escrever código para conexão e execução da query, que não faz parte diretamente da lógica e, por fim, temos que enviar a query para o banco como uma string, onde só saberemos se tem algum erro de sintaxe em tempo de execução. Então, quando o banco retornar os resultados teremos que "traduzir" este resultset em objetos para se encaixar ao nosso modelo de classes do programa. Em resumo: muito código e de difícil leitura, manutenção e depuração.
Mas como o Linq é diferente? Primeiro vamos ver os diversos tipos de formas do Linq. Primeiro temos o Linq to Objects, que nos permite selecionar e ordenar e filtrar coleções em memória. Vamos dar um exemplo:string[] Meses = {
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro"};
var MesesComA =
from mes in Meses
where mes.StartsWith("A")
orderby mes descending
select mes;
foreach (var m in MesesComA) {
Console.WriteLine(m);
}
Dê uma olhada na parte onde consultamos o array de string Meses. Neste trecho fazemos uma consulta no array Meses onde trazemos qualquer elemento que comece com a letra A e ordenamos o resultado em ordem decrescente. Desta forma acessamos os dados de forma declarativa, assim como nas linguagens funcionais. Imagine como escreveríamos este código na forma imperativa padrão...
Em Linq to Objects, podemos fazer este tipo de consulta em qualquer classe que implemente a interface IEnumerable (o array implementa essa classe, embora não pareça).
Este modelo de queries pode ser aplicado também em dados do banco de dados e arquivos XML. Mas como? Primeiro vamos falar do banco de dados - não vamos nos aprofundar muito porque o objetivo deste post é mostrar o que é Linq e do que ele capaz.
Nós fazemos consultas em bancos de dados da mesma forma declarativa que consultamos coleções de objetos. Mas Felipe, se eu tiver que trazer uma tabela inteira do banco e ter que transformá-la em array para depois fazer a consulta pode jogar esta tecnologia fora! Com certeza a Microsoft não faria isso com uma tecnologia que visa facilitar a vida dos desenvolvedores. O Linq to SQL funciona com uma outra tecnologia da linguagem: Mapeamento de entidades.
Em Linq to SQL nós temos nossos objetos no programa e os decoramos com atributos especiais de mapemento (Em outros posts eu falo e mostro mais sobre isso). De forma mais simples, nós marcamos nossas classes como "Classes de entidade" do banco de dados e informamos as tabelas e campos que nossos objetos/propriedades representam; então, quando consultamos estes objetos, o Linq monta a query para o banco de dados e "traduz" os objetos e propriedades em tabelas e campos. O Linq trata intrinsecamente todos os processos que são necesários mas não fazem parte da lógia do programa, como conexão com o banco, obtenção de registros e tradução de resultsets em objetos.
Linq to SQL vai além disso, provendo também API de atualização de dados, transação e controle de concorrência.
Linq to XML provê uma API simples e única para consultar e também criar arquivos XML; uma API muito mais simples que as atuais que conhecemos (DOM, XSL, XPath, XQuery). A sintaxe de consulta é muito semelhante à Linq to Objects, e esta padronização é muito boa nós desenvolvedores nos acostumarmos rapidamente.
Como o objetivo deste post é falar sobre uma nova tecnologia e ter uma visão geral, vou deixar os "sabores" específicos do Linq para outros posts. Até lá procurem mais e divirtam-se.
Um grande abraço a todos e até a póxima.
Show de bola!!
ResponderExcluir