Primeiramente, gostaria de parabenizar todas as equipes pernambucanas que marcarão presença na final brasileira da Imagine Cup 2008, enfatizando o time Try IT no qual Daniel (líder da CIN.NET) faz parte!
Pois bem, meu principal objetivo nesse post é esclarecer como se faz acesso a dados com a plataforma .NET. E, para tal assunto, nada mais que conviniente tratar das tecnologias ADO.NET e LINQ.
O ADO.NET é um conjunto de classes que reúnem serviços de acesso a dados para a plataforma .NET. Ele é uma evolução do ADO(ActiveX Data Object). Sua integração com o Microsoft Visual Studio é total e também é acessível de qualquer linguagem da plataforma .NET.
Sua arquitetura é baseda na figura abaixo, na qual explicarei cada camada :


- Providers do ADO.NET
Os provedores do ADO.NET são todos aqueles que estão no retângulo esquerdo da figura acima(.NET Framework Data Providers). Essa camada possui provedores especializados para acessar banco de dados de diferentes fornecedores, isso para garantir o melhor proveito da base em que se está trabalhando. Alguns dos providers que estão disponíveis são:
- Provedor do SQL Server (System.Data.SqlClient)
- Provedor do Oracle (System.Data.OracleCliente)
- Provedor do OLEDB (System.Data.OleDb)
- Connection
Essa é a camada que garante a conexão com o banco de dados. Sua principal propriedade é a string de conexão, que especifica a localização da fonte de dados; e seus principais métodos são Open e Close, usandos para abrir e fechar conexões, respectivamente. É nessa camanda que também ocorre todo o controle de transação. Alguns dos objetos de conexão são:
- SQLConnection – Do provedor para o SQL Server
- OracleConnection – Do provedor para o Oracle
- OleDbConnection – Do provedor para o OleDb
- Command
Essa camada é a responsável por receber instruções SQL e/ou Store Procedures. Assim como na camada connection, há um objeto command para cada provedor(SQLCommand, OracleCommand,etc) nessa camada. Seus principais métodos são:
- ExecuteReader: retorna um DataReader, objeto usado para leitura de uma consulta feita na fonte de dados.
- ExecuteScalar: usado quando o comando SQL retorna um único valor (Ex.: Quantidade de alunos de uma instituição)
- ExecuteNonQuery: usado quando o comando SQL não retorna nenhum tipo de dado (Ex.: Atualizar os dados do aluno que possui número de cpf igual a 123456789-0). Além de aparentemente não retornar nada, esse método retorna a quantidade de linhas afetadas.
- DataReader
É a camada usada para representar um conjunto de resultados SQL. Sua vantagem é a extrema rapidez de leitura de dados, porém não podemos modificar os resultados de uma consulta. E, como é uma camada pertencente aos providers, existe um objeto diferente para cada fonte de dados(SQLDataReader, OracleDataReader,etc). Seu principal método é o Read, usado para navegar no resultado da consuta.
Lembrando que até agora estamos trabalhando de forma conectada com o banco de dados. Para não ficar só na teoria, vai um exemplo de código:
- DataAdapter
É a camada especializada em intermediar as requisições de acesso a dados da aplicação e o banco de dados. Ele encapsula comandos SQL e/ou Store Procedures para tal. Seus principais métodos são Fill e Update, responsáveis por preencher o DataSet(veremos no próximo tópico) e atualizar o banco de dados a partir de um DataSet, respectivamente.
- DataSet
É a camada responsável por gerenciar dados previamente adquiridos por acesso a bancos de dados e/ou arquivos XML. Nessa camada há disposição de objetos que trabalham de forma desconectada ao banco. O resultado de um DataSet fica guardado na memória principal do sistema. A partir daí, podemos navegar, atualizar dados de uma consulta(ainda na mémoria) e, posteriormente, atualizar os dados no banco de dados. Um grande avanço nessa camada é a existência do DataSet Tipado. Através dele podemos detectar erros de nome em tempo de compilação. Segue dois exemplo de cógigo:
Usando DataSet Não Tipado:
SqlConnection conexao = new SqlConnection(“Data Source=MACEIO\\SQLEXPRESS”);
SqlCommand comando = new SqlCommand(“SELECT * FROM Cliente WHERE nome LIKE ‘l%’”,conexao);
conexao.Open();
SqlDataAdapter adaptador = new SqlDataAdapter(comando);
DataSet bancoDataSet = new DataSet(“Banco DataSet”);
adaptador.Fill(bancoDataSet,”Banco DataSet”);
foreach(DataRow row in bancoDataSet.Tables["Cliente"].Rows)
{
int id = Convert.ToInt32(row["id"]);
string nome = Convert.ToString(row["nome"]);
Console.WriteLine(“Cliente com id {0} e nome {1}”,id,nome);
}
Usando DataSet Tipado:
SqlConnection conexao = new SqlConnection(“Data Source=MACEIO\\SQLEXPRESS”);
SqlCommand comando = new SqlCommand(“SELECT * FROM Cliente”,conexao);
conexao.Open();
BancoDataSet bancoDados = new BancoDataSet();
int idCliente = bancoDados.Cliente.idColumn;
string nomeCliente = bancoDados.Cliente.nomeColumn;
Console.WriteLine(“Cliente com id {0} e nome {1}”, idCliente, nomeCliente);
Notem que o objeto BancoDataSet é um DataSet Tipado que representa meu banco de dados, por isso através dele podemos extrair sua tabela Cliente (bancoDados.Cliente). E quando estamos na tabela Cliente podemos extrair suas colunas(id e nome). Observem que essas extrações são feitas usando propriedades, podendo assim que erros de nome sejam detectados em tempo de compilação.
Bem, foram descritos os principais componentes na tecnologia ADO.NET.
Além do ADO.NET, existe outra nova tecnologia para acesso a dados, falo do LINQ (Language Integrated Query). Ele permite que os desenvolvedores enderecem consultas[à fonte de dados] usando a sintaxe de uma linguagem de programação gerenciada, como C# ou VB.NET, ao invés das declarações SQL. O LINQ trabalha de forma similar ao Hibernate, fazendo um mapeamento objeto-relacional. Segue um exemplo que usa tal tecnologia:
BancoLINQDataContext banco = new BancoLINQDataContext();
Table<Cliente> clientes = banco.Clientes;
var consulta = from cliente in clientes
where cliente.nome == “Lucas”
select cliente;
Antes de chegar nesse código ocorreram os seguintes passos:
1) Tinhamos uma tabela Cliente na base de dados
2) O LINQ criou um objeto na minha aplicação que representa a base de dados (BancoLINQDataContext )
3) O LINQ automaticamente criou a classe básica Cliente em minha aplicação C#
4) O LINQ automaticamente fez o mapeamento objeto-relacional (meu objeto Cliente à tabela Cliente)
Depois se fez um código que retorna todos os clientes com o nome “Lucas”. Percebe-se o uso da sintaxe do C# para tal, ao invés do comum SQL. Se bem que essa sintaxe se transformará em SQL depois! Notem também que fazemos consultas em nossos objetos, abstraindo, assim, o banco de dados.
Vale ressaltar que se fez uso na sintaxe do C# 3.0.
O objetivo desse artigo não é detalhar o LINQ, em próximas aulas/posts detalharei um pouco mais dessa nova tecnologia. Então fico por aqui e até a próxima aula!
























