You are on page 1of 58

C# - ADO .

NET para iniciantes


C#- ADO .NET para iniciantes - I
Este um mini-curso sobre ADO .NET para iniciantes usando a linguagem C#. Os requisitos mnimos para que voc aproveite este mini-curso possuir um pouco de conhecimento sobre lgica de programao. Se voc no conhece a linguagem C# pode ler os seguintes artigos :

Introduo bem bsica ao C# C# - Sintaxe e conceitos bsicos

Se voc j conhece VB .NET e esta querendo a aprender C# sugiro que voc leia o meu artigo:

VB.NET e C# - Guia rpido de referncia comparativa

O material necessrio para acompanhar o curso : ( Irei utilizar o Visual C# 2008 Express Edition) 1- Visual C# 2008 Express Edition 2- SharpDevelop 2.2 3- SQL Server 2005 Express Edition Todos esses programas so gratuitos e portanto voc no vai gastar um centavo neste curso. Durante o curso vamos desenvolver uma aplicao com acesso a dados usando C# de forma que voc ir fazendo e aprendendo na prtica os principais conceitos bsicos envolvidos. Mas chega de papo e vamos ao que interessa...

http://www.macoratti.net/

C# - ADO .NET para iniciantes


O que ADO .NET
ADO .NET a nova tecnologia para acesso a dados da plataforma .NET estando integrada ao .NET Framework e oferecendo diversas classes que permitem realizar praticamente todas as tarefas relacionadas com o acesso e manuteno de dados. ADO .NET oferece suporte a uma variedade de opes para desenvolvimento de solues com acesso a dados que permitem a comunicao com qualquer fonte de dados, desde os j conhecidos gerenciadores de banco de dados relacionais ( SGBD) como : SQL Server, MySQL, FireBird, Oracle, Sybase, Access, XML, arquivos textos, etc. Os componentes considerados os pilares da ADO.NET so o DataSet e os provedores .NET que so um conjunto de componentes que incluem os objetos : Connection - responsvel por efetuar a conexo com o banco de dados Command - responsvel por executar comandos contra o banco de dados; DataAdapter - utilizado para preencher o objeto DataSet; Atravs da ADO.NET podemos acessar dados de trs maneiras bsicas: OLE DB , SQL e ODBC. Os provedores de dados ADO .NET so livrarias de classes que permitem uma maneira comum de interagir com uma fonte especfica de dados. Cada livraria possui um prefixo que indica qual provedor ela suporta. Veja abaixo os principais provedores: Nome do Provedor API prefixo Descrio Fonte de dados com uma interface ODBC interface. Geralmente usada para banco de ODBC Data Provider Odbc dados antigos; OleDb Data Provider OleDb Fonte de dados que expe uma interface OleDb interface, ou seja: Access ou Excel; Oracle Data Provider Oracle Para banco de dados Oracle; SQL Data Provider Sql Para interao com o Microsoft SQL Server; Nota: Tambm existem provedores fornecidos por terceiros para MySQL, PostGreeSQL, FireBird, etc. Cada objeto possui uma verso para cada uma das maneiras aqui mencionadas, assim temos os objetos : OleDbConnection, OleDbCommand, OleDbDataReader, OleDataAdapter; SqlConnection, SqlCommand, SqlDataReader, SqlDataAdapter; OdbcConnection, OdbcCommand,etc. Nota: Temos tambm os provedores fornecidos por terceiros como o .NET Connector para o MySQL.
2

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Abaixo uma figura ilustrando isto:
3

Existem duas maneiras bsicas de voc realizar a conexo com uma fonte de dados com ADO .NET:

http://www.macoratti.net/

C# - ADO .NET para iniciantes 1- ) Usando um DataSet


Este modo conhecido como modo desconectado. O objeto DataSet veio para substituir com vantagens o objeto recordset (ADO) e, guarda poucas similaridades com o objeto recordset. Enquanto o objeto recordset representa uma coleo de tabelas de dados O objeto DataSet representa uma cpia do banco de dados em memria. A classe DataSet membro do namespace System.Data e representa o primeiro dos dois maiores componentes da arquitetura ADO.NET os outros membros seriam os provedores Data .NET. Podemos resumir os atributos do DataSet como segue:

baseado em XML um conjunto de dados em cache que no esta conectado ao banco de dados independente da fonte de dados Pode armazenar dados em mltiplas tabelas que podem ser relacionadas Armazena mltipla verses de dados para coluna e para cada linha em cada tabela

O DataSet fornece as principais funcionalidades para criar aplicaes para banco de dados desconectados , embora suporte tambm o modelo conectado atravs de leitores de dados ( DataReader). A classe DataSet derivada da classe System.ComponentModel.MarshalByValueComponent da qual ela recebe a habilidade de ser serializada , includa na caixa de ferramentas do VS.NET e visualmente desenhada em um descritor. Os principais mtodos da classe DataSet so :
Membro Colees Relations Tables Mtodos AcceptChanges Clear Clone Descrio Uma coleo de relaes hospedadas em um objeto DataRelationCollection que liga tabelas atravs de chaves estrangeira Uma coleo de tabelas que armazena os dados atuais Grava todas as alteraes para o DataSet Remove todas as linhas de todas as tabelas Faz uma cpia da estrutura mas no os dados de um DataSet

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Copy GetChanges GetXml GetXmlSchema HasChanges InferXmlSchema Merge ReadXml ReadXmlSchema Reset WriteXML WriteXmlSchema Faz uma cpia a estrutura e os dados de um DataSet Retorna uma cpia do DataSet com apenas as colunas alteradas ou aquelas que coincidem com o filtro definido em DataRowState Retorna uma representao exm XML dos dados Retorna uma representao XML da estrutura de um DataSet Retorna um valor indicando que existe mudanas pendentes Infere a estrutura de um DataSet baseada em um arquivo ou fluxo Mescla o DataSet com o provedor Carrega um esquema XML e dados para um DataSet Carrega um esquem XML para um DataSet Reverte o DataSet ao seu estado original Escreve os dados e o esquema XML para um arquivo ou fluxo de dados Escreve o esquema XML para um arquivo ou fluxo

2- Usando um DataReader
Os objetos DataReader uma das maneiras mais fceis para ler os dados retornados pelos objetos Command . Eles permitem acessar e percorrer os registros no modo de somente leitura e somente para frente - forward-only . O DataReader no oferece o acesso desconectado e no permite alterar ou atualizar a fonte de dados original sendo usado para obter rapidamente dados de apenas leitura. Apresenta poucos recursos mas seu desempenho muito melhor do que o oferecido pelos DataSet. As propriedades e mtodos mais usadas dos objetos DataReader so : 1. 2. 3. 4. 5. 6. 7. 8. FieldCount - informa o nmero de colunas da linha de dados atual IsClosed - Indica se o objeto DataReader esta fechado. RecordsAffected - especifica o nmero de linhas alteradas , excludas ou includas na execuo de uma declarao SQL Item (n) - obtm o valor da n-sima coluna no seu formato nativo. Close - Mtodo que fecha o objeto GetName - Mtodo que retorna o nome da n-sima coluna. Read - mtodo que permite ao DataReader avanar para o prximo registro IsDbNull - mtodo que informa se a n-sima coluna possui um valor nulo.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Para criar um objeto DataReader usamos o mtodo ExecuteReader de um objeto Command.
6

O objeto DataTable
Ao tratar com banco de dados no podemos deixar de pensar em tabelas e o objeto DataTable representa uma ou mais tabelas de dados em memria. Os objetos DataTable esto contidos no objeto DataSet e/ou DataView. Abaixo temos uma relao das principais propriedades do objeto DataTable:

Columns - representa as colunas da tabela atravs da coleo de objetos DataColumn (DataColumnCollection) Rows - representa as linhas da tabela atravs de uma coleo de objetos DataRow (DataRowCollection) PrimaryKey - representa a chave primria da tabela atraves dos objetos DataColumn TableName - define o nome do objeto DataTable via coleo DatatableCollection em um objeto DataSet AcceptChanges - Efetiva as alteraes realizadas no DataTable no banco de dados. NewRow - gera um novo objeto DataRow que representa uma linha de dados Copy - copia os dados e a estrutura do DataTable. Clear - limpa os dados de um DataTable. RejectChanges - ignora as alteraes feitas no DataTable.

O objeto DataView
O DataView tem a funo de permitir a ligao dos dados de uma fonte de dados com a interface do usurio atravs do DataBinding . Atravs do DataView podemos filtrar, ordenar, pesquisar e navegar pelos dados oferecendo diversas vises de um mesmo conjunto de dados ao usurio. Usamos o DataView para mostrar uma viso dos dados contidos em um DataTable , com isto voc pode ter vrios DataViews ligados a um mesmo DataTable , sendo que cada um exibe um viso diferente dos dados. O objeto DataTable possui um DataView padro que acessado atravs da propriedade DefaultView. As principais propriedades do objeto DataView so :

RowFilter - retorna uma expresso usada para filtrar os dados a serem exibidos pelo DataView.

http://www.macoratti.net/

C# - ADO .NET para iniciantes

RowStateFilter - Define a verso dos dados que sero exibidos pelo DataView. Oferece as seguintes opes : o CurrendRows - linhas de dados atuais (linhas no alteradas , novas) o Added - linhas de dados novas. o Deleted - Linha excluda pelo mtodo Delete o None - Nenhuma linha o ModifiedCurrent - linhas de dados que foram modificadas - verso atual o OriginalRows - linhas originais o Unchanged - Linhas no modificadas o ModifiedOriginal - linhas de dados que foram modificadas - verso original Count - informa o nmero de linhas no DataView aps a aplicao dos filtros : RowFilter e RowStateFilter Item - obtm uma linha de dados de um tabela especificada. Sort - define a coluna que iro ordenar o DataView e o tipo da ordenao ( ASC - ascendente ou DESC - descendente) Addnew - Inclui uma nova linha no DataView Table - Define qual o objeto DataTable de origem para o DataView Delete - exclui uma linha do DataView Find - Busca por uma linha no DataView

Creio que para um incio j temos muita informao, na sequncia irei mostrar como realizar uma conexo com um banco de dados usando ADO .NET com C#. Eu sei apenas C# mas eu gosto... referncias:

http://www.macoratti.net/

C# - ADO .NET para iniciantes C# - ADO .NET para Iniciantes - II


Este um mini-curso sobre ADO .NET para iniciantes usando a linguagem C#. Esta chegando agora ??? Ento acompanhe o primeiro artigo:

C#- ADO .NET para iniciantes - I

Os requisitos mnimos para que voc aproveite este mini-curso possuir um pouco de conhecimento sobre lgica de programao. Se voc no conhece a linguagem C# pode ler os seguintes artigos :

Introduo bem bsica ao C# C# - Sintaxe e conceitos bsicos

Se voc j conhece VB .NET e esta querendo a aprender C# sugiro que voc leia o meu artigo:

VB.NET e C# - Guia rpido de referncia comparativa

O material necessrio para acompanhar o curso : (Irei utilizar o Visual C# 2008 Express Edition) 1- Visual C# 2008 Express Edition 2- SharpDevelop 2.2 3- SQL Server 2005 Express Edition

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Todos esses programas so gratuitos e portanto voc no vai gastar um centavo neste curso. Durante o curso vamos desenvolver uma aplicao com acesso a dados usando C# de forma que voc ir fazendo e aprendendo na prtica os principais conceitos bsicos envolvidos. Mas chega de papo e vamos ao que interessa...
9

As Classes e os Namespaces da ADO .NET

http://www.macoratti.net/

C# - ADO .NET para iniciantes


O seis principais namespaces (espaos de nome) da ADO .NET so mostrados abaixo resumidamente :
Namespaces Descrio o principal espao de nomes da ADO .NET e contm as classes usadas por todos os provedores; classes que representam tabelas, colunas, linhas e tambm a classe DataSet. Alm disso possui diversas interfaces como IDbCommand, IDbConnection, e IDbDataAdapter que so usadas por todos os provedores gerenciados. Define as classes comuns usadas como classes base para os provedores de dados. Todos eles compartilham estas classes. Ex: DbConnection e DbDataAdapter. Define classes que trabalham com fonte de dados OLE DB usando o provedor .NET OleDb. Define classes que trabalham com fonte de dados ODBC usando o provedor .NET Odbc. 10

System.Data

System.Data.Commom System.Data.OleDb System.Data.Odbc

System.Data.SqlClient Define classes que trabalham com fonte de dados SQL Server 7.0 ou superior. System.Data.SqlTypes Define classes que representam tipos de dados especficos para o SQL Server.

A ADO .NET possui 3 tipos distintos de classes referenciadas como:


Disconnected - Classes que fornecem a estrutura bsica para o framework ADO .NET. Ex: A classe DataTable. Os objetos desta classe so capazes de armazenar dados sem qualquer dependncia de um provedor especfico; Shared - Classes que Formam as classes bases para os provedores de dados e so compartilhadas entre todos os provedores; Data Providers - So classes que so usadas com diferentes tipos de fonte de dados para realizar operaes de gerenciamento de dados em um banco de dados especfico.

Os provedores de dados contm objetos Connection, Command, DataAdatper e DataReader que foram apresentados na primeira parte deste artigo.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Com ADO .NET voc primeiro cria um objeto Connection e fornece ao mesmo informao sobre a string de conexo. A seguir voc criar um objeto Command e fornece a ele detalhes da instruo SQL que dever ser executada. Esta informaes pode usar parmetros. Se o objeto Command retornar um conjunto de registros e voc decidir us-lo dever criar um objeto DataAdapter e preencher um objeto DataSet ou DataTable.
11

Usando o objeto Connection


Um objeto Connection cria uma ligao (ou conexo) com uma fonte de dados especfica. Este objeto deve conter a informao necessria para se conectar a fonte de dados usando informaes como o provedor, o caminho da base de dados, o usurio e a senha (se necessrio). Esta informao esta contida na string de conexo. Esta informao tambm pode ser armazenada no arquivo web.config , em um arquivo texto, no registro do windows, etc. Cada tipo de provedor de dados possui um objeto connection especfico, assim um provedor de dados que trabalha com uma fonte de dados SQL Server inclui uma classe SqlConnection que realiza este tipo de operao. J um provedor que trabalha com uma fonte de dados OLE DB possui uma classe OleDbConnection. Obs: Podemos tambm efetuar a conexo com outros banco de dados como MySQL, FireBird, PostGreSQL , DB2, etc. Neste caso ser necessrio usar um conector apropriado geralmente fornecido pelo fabricante ou usar um provedor de dados ODBC(no muito recomendvel).

http://www.macoratti.net/

C# - ADO .NET para iniciantes


De forma geral podemos descrever as propriedades para uma classe Connection assim :
Propriedade ConnectionString DataBase DataSource Descrio Contm informaes pelo objeto Connection para efetuar a conexo com o banco de dados; Retorna o nome do banco de dados aps a conexo ser aberta; Retorna o nome da instncia do banco de dados usado pelo objeto Connection; Retorna o estado atual da conexo: Valores possveis :

12

State

Broken Closed Connecting Executing Fetching Open

http://www.macoratti.net/

C# - ADO .NET para iniciantes


A seguir temos o trecho de cdigo genrico usado para efetuar a conexo com o SQL Server : using System.Data; using System.Data.SqlClient; //1-definio das informaes para montar a string de conexo string Server = "localhost"; string Username = "usuario"; string Password = "senha"; string Database = "banco de dados"; //2-montagem da string de conexo string ConnectionString = "Data Source=" + Server + ";"; ConnectionString += "User ID=" + Username + ";"; ConnectionString += "Password=" + Password + ";"; ConnectionString += "Initial Catalog=" + Database; //3-cria uma instncia do objeto Connection em memria SqlConnection SQLConnection = new SqlConnection(); try { //4- atribui a string de conexo e abre a conexo SQLConnection.ConnectionString = ConnectionString; SQLConnection.Open(); //realiza alguma operao ...... } catch (Exception Ex) { MessageBox.Show(Ex.Message); }
13

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Para a conexo com o SQL Server podemos tambm declarar e instanciar o objeto SqlConnection ao mesmo tempo conforme o cdigo abaixo:
14

SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");


Neste caso o objeto SqlConnection instanciado usa um construtor com um nico argumento do tipo string , a famosa string de conexo. Veja a seguir sua descrio detalhada :
Data Source Initial Catalog Integrated Security User ID Password Identifica o servidor e pode ser a mquina local (localhost), um dns ou um endereo IP. O nome do banco de dados Defina para SSPI para fazer a conexo usando a autenticao do WIndows.(Usar Integrated Security
seguro somente quando voc esta em uma mquina fora da rede)

Nome do usurio definido no SQL Server. Senha do usurio definida no SQL Server.

Um exemplo de conexo com o meu servidor MAC/SQLEXPRESS usando o banco de dados Northwind.mdf com o usurio macoratti e senha 123456 seria: SqlConnection conn = new SqlConnection("Data Source=MAC/SQLEXPRESS;Initial Catalog=Northwind;User ID=macoratti;Password=123456"); A sequncia de operaes que ocorrem quando da abertura de uma conexo pode ser resumida assim:
Instancia um objeto SqlConnection ou OledbConnection;

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Abre a conexo; Passa a conexo para outro objeto ADO .NET(command); Realiza a operao no banco de dados(uma consulta); Fecha a conexo; 15

Um exemplo completo bem simples pode ser visto a seguir: using System; using System.Data; using System.Data.SqlClient; /// <summary> /// Demonstra como trabalhar abrir uma conexo com SqlConnection /// </summary> class SqlConnectionDemo{ static void Main() { // 1. Instancia a conexo(objeto SqlConnection) SqlConnection conn = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI"); // // define um SqlDataReader nulo SqlDataReader dr = null; try { // 2. Abre a conexo

http://www.macoratti.net/

C# - ADO .NET para iniciantes


conn.Open(); // 3. Passa conexo para o objeto command SqlCommand cmd = new SqlCommand("select * from Customers", conn); // // 4. Usa conexo // obtm o resultado da consulta dr = cmd.ExecuteReader(); // imprime o codigo do cliente para cada registro while (dr.Read()) { Console.WriteLine(dr[0]); } } finally { // fecha o reader if (dr != null) { dr.Close(); } // 5. Fecha a conexo if (conn != null) { conn.Close(); } } } } O cdigo usa um objeto SqlCommand o qual realiza uma consulta na tabela Customers.
16

http://www.macoratti.net/

C# - ADO .NET para iniciantes


O resultado retornado como um SqlDataReader e o loop While percorre e l a primeira coluna de cada linha do conjunto de registros retornados que a coluna CustomerID. (poderamos ter obtido mais colunas como dr[1], dr[2], etc.) Nota: Podemos tambm obter os dados das colunas pelo nome dos campos : Ex: dr["CustomerID"]. Ao usar o objeto Connection voc deve sempre ter o cuidado de fech-lo caso contrrio haver impacto no desempenho da sua aplicao, por isso estou usando um bloco Try/Finally, onde o bloco Finally garante que a conexo ser fechada pois sempre ser executado. Note que tomamos a precauo de verificar se a conexo e o objeto DataReader eram nulos antes de fech-los para evitar uma exceo. Este exemplo mostra como usar o SqlConnection com o objeto SqlDataReader o qual requer que a conexo seja fechada explicitamente. No prximo artigo irei falar sobre o objeto SqlCommand.
17

http://www.macoratti.net/

C# - ADO .NET para iniciantes C# - ADO .NET para Iniciantes - III - Command (SqlCommand)
Este um mini-curso sobre ADO .NET para iniciantes usando a linguagem C#. Esta chegando agora ??? Ento acompanhe as dois primeiros artigos:

18

C#- ADO .NET para iniciantes - I C#- ADO .NET para iniciantes - II

Os requisitos mnimos para que voc aproveite este mini-curso possuir um pouco de conhecimento sobre lgica de programao. Se voc no conhece a linguagem C# pode ler os seguintes artigos :

Introduo bem bsica ao C# C# - Sintaxe e conceitos bsicos

Se voc j conhece VB .NET e esta querendo a aprender C# sugiro que voc leia o meu artigo:

VB.NET e C# - Guia rpido de referncia comparativa

O material necessrio para acompanhar o curso : (Irei utilizar o Visual C# 2008 Express Edition)

http://www.macoratti.net/

C# - ADO .NET para iniciantes


1- Visual C# 2008 Express Edition 2- SharpDevelop 2.2 3- SQL Server 2005 Express Edition Todos esses programas so gratuitos e portanto voc no vai gastar um centavo neste curso. Durante o curso vamos desenvolver uma aplicao com acesso a dados usando C# de forma que voc ir fazendo e aprendendo na prtica os principais conceitos bsicos envolvidos. Mas chega de papo e vamos ao que interessa...
19

Falando um pouco sobre o objeto SqlCommand


O objetivo desta aula descrever o objeto SqlCommand e como voc pode us-lo para interagir com um banco de dados. Resumindo os objetivos so:

Conhecer o que o objeto SqlCommand; Aprender como usar o mtodo ExecuteReader para consultar dados; Aprender como usar o mtodo ExecuteNonQuery para inserir ou excluir dados; Aprender a usar o mtodo ExecuteScalar para retornar um valor nico;

Veja na tabela a seguir um resumo para cada um dos mtodos citados:


Mtodo ExecuteReader Descrio Executa a consulta e retorna um objeto SqlDataReader;

Executa a consulta e no retorna nenhuma coleo. Usado para instrues INSERT, DELETE e UPDATE ExecuteNonQuery onde retorna o nmero de registros afetados. Ex:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


SqlCommand sqlComm = new SqlCommand("DELETE FROM Categories WHERE CategoryID=1", sqlConn); sqlComm.ExecuteNonQuery();

20

ExcecuteScalar

Executa a consulta e retorna um nico valor.(uma linha e uma coluna)

Introduo
Um objeto SqlCommand permite que voc especifique qual tipo de interao voc deseja realizar em um banco de dados: selecionar, incluir, modificar e excluir dados e pode ser usado para dar suporte em operaes em um cenrio de gerenciamento de dados no modelo desconectado mas irei focar nesta aula como usar o SqlCommand de forma simples e isolada.
A classe SqlCommand usada para representar uma instruo SQL ou stored procedure disparada com o objetivo de inserir, atualizar, excluir ou selecionar informaes de uma fonte de dados. A sua posio na hierarquia de classes da plataforma .NET dada a seguir: System.Object System.MarshalByRefObject System.ComponentModel.Component System.Data.Common.DbCommand System.Data.Odbc.OdbcCommand System.Data.OleDb.OleDbCommand System.Data.OracleClient.OracleCommand System.Data.SqlClient.SqlCommand System.Data.SqlServerCe.SqlCeCommand

Para criar um objeto SqlCommand podemos usar um construtor criando uma instncia da classe SqlCommand passando a string SQL que representa qual operao desejamos realizar contra o banco de dados e o objeto SqlConnection que dever ter sido criado anteriormente contendo a conexo com a fonte de dados:

http://www.macoratti.net/

C# - ADO .NET para iniciantes SqlCommand cmd = new SqlCommand("select * from Clientes", conn);

21

cmd - instncia da classe SqlCommand select * from clientes - instruo sql para selecionar todos os clientes da tabela Clientes; conn - a conexo com o banco de dados;

Podemos ento realizar as seguintes operaes com o objeto SqlCommand:


Nos exemplos abaixo irei usar uma tabela chamada Clientes com a seguinte estrutura:

id - int - primary Key nome - varchar(50) email - varchar(50)

1- Consultar dados
Para consultar dados voc usa uma instruo SQL SELECT para retornar um conjunto de dados para visualizao. Para obter este resultado voc pode usar o mtodo ExecuteReader o qual retorna um objeto SqlDataReader da seguinte forma:

// 1. Instancia um novo comando com uma consulta e uma conexo SqlCommand cmd = new SqlCommand("select * from Clientes", conn); // 2. Chama o mtodo ExecuteReader para obter o resultado da consulta SqlDataReader dr = cmd.ExecuteReader();

http://www.macoratti.net/

C# - ADO .NET para iniciantes 2- Incluir dados


Para inserir registros em um banco de dados use o mtodo ExecuteNonQuery do objeto SqlCommand :
22

// prepara um comando SQL para incluir dados usando a instruo INSERT INTO string incluiSQL = @" insert into Clientes (Nome, Email) values ('Macoratti', 'macoratti@ig.com.br')"; // 1. Instancia um novo comando com uma consulta e uma conexo SqlCommand cmd = new SqlCommand(incluiSQL , conn); // 2. Chama o mtodo ExecuteNonQuery para enviar o comando cmd.ExecuteNonQuery();
Aqui alteramos ligeiramente a forma de instanciar um objeto SqlCommand passando a varivel incluiSQL como parmetro. Um detalhe importante que estamos incluindo valores para os campos Nome e Email mas a tabela possui um campo id que a chave primria que no faz parte da instruo. Isto devido ao fato da incluso deste campo ser feita de forma automtica pelo SQL Server. Se voc tentar incluir um valor para o campo id no cdigo ir obter uma exceo em tempo de execuo.

3- Atualizar dados
O mtodo ExecuteNonQuery tambm usado para atualizao de dados:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


// prepara um comando SQL para incluir dados usando a instruo Update string atualizaSQL = @"update Clientes set Nome = 'Macoratti' where id = 1"; // 1.Instancia um novo comando com uma consulta sql SqlCommand cmd = new SqlCommand(atualizaSQL ); // 2. Define a propriedade Connection cmd.Connection = conn; // 3. Chama o mtodo ExecuteNonQuery para enviar o comando cmd.ExecuteNonQuery();
Neste cdigo usamos um construtor SqlCommand que possui somente um comando, logo em seguida ns atribumos o objeto SqlConnection (conn) usando a propriedade Connection do objeto SqlCommand cmd; Com isso mostramos que podemos alterar o objeto Connection a qualquer tempo. 23

4- Excluir dados
O mtodo ExecuteNonQuery tambm usado para excluir dados:

// prepara um comando SQL para incluir dados usando a instruo DELETE string excluiSQL = @"delete from Clientes where id = 1";

http://www.macoratti.net/

C# - ADO .NET para iniciantes


// 1. Instantcia um novo comando SqlCommand cmd = new SqlCommand(); // 2. Define a propriedade CommandText cmd.CommandText = excluiSQL ; // 3. Define a propriedade Connection cmd.Connection = conn; // 4. Chama o mtodo ExecuteNonQuery para enviar o comando cmd.ExecuteNonQuery();
Neste exemplo usamos o construtor SqlCommand sem parmetros mas logo em seguida definimos explicitamente as propriedades CommandText e Connection do objeto SqlCommand, cmd. Com isso mostramos que podemos alterar o objeto Connection e Command a qualquer tempo. 24

5- Obtendo valores
s vezes tudo o que voc precisa do banco de dados um valor nico que pode ser o resultado de uma contagem, soma, mdia, ou outro valor agregado. Usar um ExecuteReader e calcular o resultado no seu cdigo no a forma mais eficiente de fazer isso. A melhora maneira deixar o banco de dados realizar a operao e retornar apenas um valor nico como resultado. Para isso usamos o mtodo ExecuteScalar:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


// 1. Instantcia um novo comando SqlCommand cmd = new SqlCommand("select count(*) from Clientes", conn); // 2. Chama o mtodo ExecuteScalar para enviar o comando int count = (int)cmd.ExecuteScalar();
A consulta no construtor SqlCommand obtm a contagem de todos os registros a partir da tabela Clientes e ir retornar somente o valor da contagem. O mtodo ExecuteScalar retorna um valor do tipo Object, temos que efetuar uma coero forada (casting) para converter o valor para um int.
using System.Data.SqlClient; namespace adonetCshp_3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string connetionString = null; SqlConnection cnn = default(SqlConnection); SqlCommand cmd = default(SqlCommand); string sql = null; connetionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=SSPI";

25

http://www.macoratti.net/

C# - ADO .NET para iniciantes


sql = "Select Count(*) from clientes"; cnn = new SqlConnection(connetionString); try { cnn.Open(); cmd = new SqlCommand(sql, cnn); Int32 contador = Convert.ToInt32(cmd.ExecuteScalar()); cmd.Dispose(); cnn.Close(); MessageBox.Show(" No. de linhas " + contador ); } catch (Exception ex) { MessageBox.Show("No foi possvel abrir a conexo com o banco de dados ! " + ex.Message.ToString()); } } } }

26

A seguir um exemplo realizando as operaes CRUD na tabela Clientes do banco de dados Cadastro.mdf:
using System; using System.Data; using System.Data.SqlClient; class ExecutaInsertUpdateDelete { public static void exibirRegistro(SqlCommand comando, string ID) { comando.CommandText ="SELECT codigo, nome FROM Clientes WHERE codigo = '" + ID + "'"; SqlDataReader dr = comando.ExecuteReader(); while (dr.Read())

http://www.macoratti.net/

C# - ADO .NET para iniciantes


{ listBox1.Items.Add("dr[\" codigo\"] = " + dr["codigo"]); listBox1.Items.Add("dr[\" nome\"] = " + dr["Nome"]); } dr.Close(); } public static void Main() { connetionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=SSPI"; SqlConnection conexaoSql =new SqlConnection(connetionString) ; SqlCommand comando = conexaoSql.CreateCommand(); comando.CommandText ="INSERT INTO Clientes (codigo, nome) VALUES (" + " 19, 'Macoratti')"; conexaoSql.Open(); int numeroLinhasAfetadas = comando.ExecuteNonQuery(); l listBox1.Items.Add("Numero de linhas afetadas = " + numeroLinhasAfetadas); exibirRegistro(comando, "9"); comando.CommandText = "UPDATE Clientes SET Nome = 'Novo' WHERE codigo = 19"; numeroLinhasAfetadas = comando.ExecuteNonQuery(); listBox1.Items.Add("Numero de linhas atualizadas = " + numeroLinhasAfetadas); exibirRegistro(comando, "9"); comando.CommandText ="DELETE FROM Clientes WHERE codigo = 19"; numeroLinhasAfetadas = comando.ExecuteNonQuery(); listBox1.Items.Add("Numero de linhas deletadas = " + numeroLinhasAfetadas); conexaoSql.Close(); } }

27

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Para encerrar eu gostaria de falar sobre o bloco using: A instruo using declara o incio de um bloco Using e opcionalmente adquire os recursos do sistema que o bloco controla. Um bloco Using garante a liberao de um ou mais dos tais recursos quando seu cdigo estiver finalizado com eles. Isso torna-os disponveis para uso por outros cdigos.
As Classes SqlConnection e SqlCommand implementam a interface IDisposable e isto significa que eles podem usar recursos no gerenciados e liberar tais recursos trabalho do desenvolvedor, de forma que depois de usar estas classes temos que chamar o mtodo Dispose(). Se ocorrer uma exeo no acesso ao banco de dados temos que ter certeza que o Dispose() foi chamado , este um motivo para usar a palavra reservada Using.

28

Obs: Recursos gerenciados so descartados pela coletor de lixo .NET Framework (GC) sem qualquer codificao extra de sua parte. Voc no precisa de um bloco Using para recursos gerenciados. Veja abaixo um exemplo de bloco Using para criar uma tabela em um banco de dados; a string de conexo esta sendo obtida a partir do arquivo de configurao
using (SqlConnection con = new SqlConnection(Macoratti.Properties.Settings.Default.MacorattiConnectionString)) { con.Open(); try { using (SqlCommand command = new SqlCommand("CREATE TABLE Macoratti (Codigo INT, Nome TEXT, Endereco TEXT)", con)) { command.ExecuteNonQuery(); }

http://www.macoratti.net/

C# - ADO .NET para iniciantes


} catch { Console.WriteLine("Tabela no pode ser criada"); } }

29

Outro exemplo usando Using e comparando com a sintaxe tradicional sem usar Using:
SqlConnection cn = null; SqlCommand cm = null; using (SqlConnection cn = new SqlConnection(connectionString)) { using (SqlCommand cm = new SqlCommand(commandString, cn)) { cn.Open(); cm.ExecuteNonQuery(); } } try { cn = new SqlConnection(connectionString); cm = new SqlCommand(commandString, cn); cn.Open(); cm.ExecuteNonQuery(); } finally { if (null != cm); cm.Dispose(); if (null != cn) cn.Dispose(); }

Os dois trechos de cdigo acima so equivalentes.No prximo artigo irei falar sobre o objeto SqlDataReader

http://www.macoratti.net/

C# - ADO .NET para iniciantes C# - ADO .NET para iniciantes IV - DataReader (SqlDataReader)
30

Esta chegando agora ??? Ento acompanhe as dois primeiros artigos:

C#- ADO .NET para iniciantes - I

http://www.macoratti.net/

C# - ADO .NET para iniciantes


C#- ADO .NET para iniciantes - II C#- ADO .NET para iniciantes - III

31

O objeto DataReader da ADO .NET pertence ao namespace System.Data e apresenta as seguintes especificidades:

Acessa as informaes em uma fonte de dados de forma mais rpida; usado somente para exibir rapidamente as informaes de uma base de dados; Seus dados obtidos so somente leitura e possvel somente caminhar para frente na navegao pelos dados; Ele exige que a conexo esteja aberta enquanto estiver sendo usado e reflete o estado mais atualizado possvel dos dados;

Voc vai encontrar na leitura tcnica a designao de que o um DataReader forward-only (somente para frente) e read-only (somente-leitura). O resultado gerado por um DataReader retornado pela execuo da consulta e armazenada no buffer da rede no cliente at que seja requisitado atravs do mtodo Read(). Resumindo as funcionalidades do DataReader: - um objeto somente leitura e para frente, ou seja, no voc no pode navegar aleatoriamente; - Opera conectado ao banco, assim, enquanto estivermos utilizando-o para obter os dados do banco, estaremos com a conexo do banco aberta; - Opera apenas com uma tabela por vez; voc deve configurar a string SQL para a primeira tabela, conectar no banco, coletar suas informaes e desconectar do banco. Para a segunda tabela voc dever repetir o processo; Nota: A conexo utilizada pelo DataReader deve ser aberta e fechada manualmente.( exceto quando voc informa que ela dever ser fechada de forma automtica usando a enumerao CommandBehavior.CloseConnection)
Voc deve usar um DataReader em sua aplicao quando:
Voc

precisar trabalhar somente com uma tabela de dados por vez

http://www.macoratti.net/

C# - ADO .NET para iniciantes


voc no precisar usar cache de dados voc precisar somente exibir os dados de uma tabela voc precisar acessar de forma rpida e de uma vez os dados de uma forma somente-leitura e somente-para-frente voc precisar processar uma quantidade de dados muito grande para caber na memria

32

Nota: O DataAdapter usa o DataReader par preencher o DataSet. Desta forma , o desempenho ganho pela utilizao do DataReader que voc salva na memria os dados que o DataSet ir consumir.

O roteiro bsico para utilizao de um objeto DataReader o seguinte:


criar uma instncia de um objeto Command; criar um objeto DataReader(); chamar o mtodo ExecuteReader do objeto Command(); Obter o retorno da consulta usando o mtodo Read();

Abaixo temos um exemplo bem bsico do cdigo usando SqlDataReader:


using System.Data; using System.Data.SqlClient; string connString = "Data Source=server;Initial Catalog=database;Persist Security Info=True;User ID=sa;Password=xxx" SqlConnection adoConn = new SqlConnection(connString); adoConn.Open(); // novo command string sql = "SELECT * FROM Tabela"; SqlCommand adoCmd = new SqlCommand(sql, adoConn); SqlDataReader adoDR = adoCmd.ExecuteReader(); if (adoDR.HasRows)

http://www.macoratti.net/

C# - ADO .NET para iniciantes


{ while (adoDR.Read()) { Response.Write(adoDR["0"].ToString()); } } adoDR.Close(); adoDR.Dispose(); adoCmd.Dispose(); adoConn.Close(); adoConn.Dispose();

33

Observe as linhas em negrito onde temos: 1-) A criao de um objeto SqlCommand usando uma instruo SQL e a conexo SqlCommand adoCmd = new SqlCommand(sql, adoConn); 2-) A criao de um objeto SqlDataReader e utilizao do mtodo ExecuteReader() do objeto SqlCommand; SqlDataReader adoDR = adoCmd.ExecuteReader(); 3-) Utilizao do mtodo Read() para ler o resultado while (adoDR.Read()) Veja a seguir outra forma de obter o mesmo resultado:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


using System.Data.SqlClient; public void exibirDados() { string consulta = "SELECT * FROM Tabela"; SqlConnection conexao = new SqlConnection("conString"); SqlCommand comando = new SqlCommand(consulta, conexao); SqlDataReader dr = null; try { conexao.Open(); dr = comando.ExecuteReader(); while (dr.Read()) { Console.WriteLine(dr.GetString(1)); } } catch{ Console.WriteLine("Erro."); } finally { dr.Close(); conexao.Close(); } }

34

Observe que abrimos uma conexo com a fonte de dados e aps executar a consulta usando o mtodo ExecuteReader() atribumos o resultado ao objeto SqlDataReader dr.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Para exibir o resultado usamos um lao While onde percorremos o SqlDataReader usando o mtodo Read(), este mtodo avana sempre para o prximo registro e retorna True enquanto existir um registro a ser lido. Para ler os valores retornados podemos usar o nome da coluna, o seu ndice ou os mtodos Get do SqlDataReader:

35

dr["nome_da_Coluna"] dr[0] dr.getString(0)

O objeto SqlDataReader possui alguns mtodos para obter os dados das colunas como: GetString(), GetValue(), getDateTime(), GetDouble(), GetChar(), GetGuid(), GetInt16(), GetInt32(), etc..

Cada um destes mtodos usa um valor inteiro como ndice baseado em zero e representa a coluna a ser obtida. Assim dr.GetString(0) retorna o valor da primeira coluna. Para detalhes veja o link: http://msdn.microsoft.com/enus/library/system.data.sqlclient.sqldatareader_members.aspx No primeiro exemplo antes de iniciarmos o lao e a leitura do DataReader usamos o mtodo HasRows que usado para verificar se existem linhas no DataReader, se existir ele retorna True, se no retorna False e neste caso nem iniciaremos a leitura do mesmo. O enumerador CommandBehavior possui o item CloseConnection() que pode ser usado com o mtodo ExecuteReader do objeto SqlCommand() da seguinte forma:

dr = comando.ExecuteReader(CommandBehavior.CloseConnection)
neste caso estamos passando o CommandBehavior.CloseConnection() como parmetro para o objeto ExecuteReader e com isso no temos a necessidade de fechar a conexo explicitamente com a fonte de dados, pois ao percorrer os dados o prprio DataReader ir fechar a conexo quando o mtodo Close() do DataReader for chamado.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Veja um exemplo usando este recurso:
using System.Data.SqlClient; public void exibirDados(){ SqlConnection conexao = new SqlConnection("connString"); SqlCommand comando = new SqlCommand("SELECT * FROM TABELA", conexao); SqlDataReader dr=null; try { conexao.Open();

36

dr = comando.ExecuteReader(CommandBehavior.CloseConnection);
while (dr.Read()) { Console.WriteLine(dr.GetString(1)); } } catch (Exception ex) { Console.WriteLine("Erro."); } finally {

dr.Close();
} }

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Observe que neste caso no fechamos a conexo explicitamente com o banco de dados. Para verificar se a conexo ainda esta aberta podemos verificar o seu estado usando o cdigo a seguir:
37

if (conexao.State != ConnectionState.Closed) conexao.Close();

Exemplo prtico usando DataReader


No exemplo a seguir vamos criar uma aplicao C# com uma interface bem simples que permite aos usurios procurar pelo nome dos produtos na tabela Products do banco de dados Northwind.mdf. Este exemplo usar o seguintes recursos:

Visual C# 2008 Express Edition - para criar o projeto da aplicao C#; SQL Server 2005 Express Edition - para gerenciar o banco de dados Northwind.mdf; Criao de consultas parametrizadas - definindo parmetros na instruo SQL; Utilizao do mtodo ExecuteReader - executando a instruo SQL que o objeto Command representa e retornando o objeto DataReader;

Abra o Visual C# Express Edition e crie um novo projeto do tipo Windows Application com o nome uDataReader; A seguir no formulrio padro inclua os controles : Label, Button - btnProcurar , ListBox - lbDados e TextBox - txtcriterio conforme o leiaute abaixo:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


38

Agora defina o namespace : using System.Data.SqlClient; No evento Click do boto de comando Procurar insira o seguinte cdigo: private void btnProcurar_Click(object sender, EventArgs e) { //define os objetos DataReader, Connection e Command SqlDataReader sqldr = null; SqlConnection con = null;

http://www.macoratti.net/

C# - ADO .NET para iniciantes


SqlCommand cmd = null; try { // Abre a conexo com o banco de dados Northwind no SQL Server 2005 Express // .\SQLExpress o nome default do servidor // initial Catalog - indica o banco de dados // String usando Windows Authentication (Trusted Connection): string ConnectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI"; con = new SqlConnection(ConnectionString); con.Open(); // define um comando para selecionar os produtos e preos da tabela products string CommandText = "SELECT ProductName,UnitPrice " + "FROM Products " + "WHERE (ProductName LIKE @criterio)"; //associa comando a conexo cmd = new SqlCommand(CommandText); cmd.Connection = con; // Define o parmetro @criterio e seu tipo de dados cmd.Parameters.Add( new SqlParameter( "@criterio", // o nome do parametro System.Data.SqlDbType.NVarChar, // o tipo de dado SqlDbType 40, // o tamanho do parametro "ProductName")); // o nome da coluna na tabela a qual se aplica // Preenche o valor do parmetro com o texto informado // na caixa de texto : txtcriterio cmd.Parameters["@criterio"].Value = txtcriterio.Text+"%"; // executa a consulta sqldr = cmd.ExecuteReader(); lbDados.Items.Clear();
39

http://www.macoratti.net/

C# - ADO .NET para iniciantes


// preenche o listBox com os valores retornados // usa o mtodo read() para percorrer o datareader while (sqldr.Read()) { lbDados.Items.Add(sqldr["ProductName"].ToString() + " - " + sqldr["UnitPrice"].ToString()); } } catch (Exception ex) { // exibe mensagem de erro MessageBox.Show(ex.Message); } finally { // fecha o data reader e a conexo if (sqldr != null) sqldr.Close(); if (con.State == ConnectionState.Open) con.Close(); } }
40

Note que estamos usando o parmetro @criterio para receber o valor informado na caixa de texto na instruo de comando SQL :

SELECT ProductName,UnitPrice FROM Products WHERE (ProductName LIKE @criterio)";

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Ao atribuir o valor ao parmetros inclumos o caractere % ao final do valor digitado: cmd.Parameters["@criterio"].Value = txtcriterio.Text+"%"; Aps executar o comando via mtodo ExecuteReader() percorremos o DataReader com o mtodo Read() e obtemos os valores usando a sintaxe: sqldr["ProductName"].ToString() + " - " + sqldr["UnitPrice"].ToString() O resultado para a letra C pode ser visto abaixo:
41

Pegue o projeto completo aqui:

uDataReader.zip

http://www.macoratti.net/

C# - ADO .NET para iniciantes Usando uma Stored Procedure


Podemos tambm gerar um DataReader executando uma stored procedure. Supondo que voc tenha uma stored procedure criada no banco de dados com o nome listaClientes que obtm os clientes para um determinado id. O cdigo usado para definir o comando e passar o parmetro pode ser escrito assim: 1 SqlCommand storedProcCommand = new SqlCommand ("listaClientes", con); 2 storedProcCommand.CommandType = CommandType.StoredProcedure; 3 storedProcCommand.Parameters.Add("@ID",clienteID); 4 SqlDataReader reader = storedProcCommand.ExecuteReader(); 5 while (reader.Read()) {//} - Na primeira linha construmos o objeto SqlCommand com o nome da stored procedure usando a conexo com o banco de dados; - Na linha 2 o objeto Sqlcommand define que estar executando uma stored procedure; - Na linha 3 inclumos o parmetro no objeto SqlCommand. Observe o uso do smbolo @ usado para identificar um parmetro no SQL Server. - Na linha 4 usamos o mtodo ExecuteReader() para executar a stored procedure e retornar um DataReader; - Na linha 5 iniciamos a leitura do DataReader; Lembrete:
Um DataReader sempre mais rpido que um DataSet ??? A resposta : DEPENDE... A vantagem do DataReader e no ter que carregar todo o contedo da tabela em memria, e retornar os registros medida que so disponibilizados pelo banco de dados; enquanto que o DataSet aguarda o fim da execuo da consulta para prosseguir a execuo.

42

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Quando voc usa um DataSet, todos os registros retornados so carregados na memria, para depois serem processados. O DataReader carrega na memria apenas o registro atual. Por isso, no possvel acessar registros anteriores.( Ele forward-only lembra-se ?) Ento, se voc usar o DataReader para ler TODOS os registros do banco de dados e carreg-los na memria esta fazendo com que o seu DataReader se comporte como um DataSet. Ora !! neste caso melhor um DataSet pois exige menos cdigo para ser tratado.

43

Conclumos assim esta apresentao sobre o objeto DataReader e sua utilizao com o SqlDataReader. No prximo artigo irei falar sobre o objeto SqlDataAdapter e DataSet.

http://www.macoratti.net/

C# - ADO .NET para iniciantes C# - ADO .NET para iniciantes IV - SqlDataAdapter e DataSet
44

Esta chegando agora ??? Ento acompanhe as dois primeiros artigos:

C#- ADO .NET para iniciantes - I

http://www.macoratti.net/

C# - ADO .NET para iniciantes


C#- ADO .NET para iniciantes - II C#- ADO .NET para iniciantes - III C#- ADO .NET para iniciantes - IV

45

Se voc j conhece VB .NET e esta querendo a aprender C# sugiro que voc leia o meu artigo:

VB.NET e C# - Guia rpido de referncia comparativa

O material necessrio para acompanhar o curso : ( Irei utilizar o Visual C# 2008 Express Edition) 1- Visual C# 2008 Express Edition (vou dar preferncia ao Visual C#) 2- SharpDevelop 2.2 (opcional) 3- SQL Server 2005 Express Edition No artigo anterior escrevemos sobre o DataReader, e, embora o objeto DataReader seja rpido e muito simples de usar, em muitas situaes, teremos que efetuar operaes em nossos dados que vo alm da exibio e movimentao somente para frente; muitas vezes teremos que realizar operaes de incluso, alterao, excluso, etc., e, neste caso as classes DataSet e SqlDataAdapter so as mais indicadas para serem usadas.

A classe DataSet
O DataSet representa um conjunto de dados em memria retornados de uma fonte de dados e consiste de uma coleo de objeto DataTable que voc pode inter-relacionar usando os objetos DataRelations. Voc tambm pode forar a integridade dos dados em um DataSet usando os objetos UniqueConstraints e ForeignKeyConstraints.
Um DataSet essencialmente um banco de dados em memria, contendo mltiplas tabelas, constraints, consultas, ordenaes e a habilidade de persistir o seu estado em um arquivo XML. Voc pode usar um SqlDataAdapter para preencher um DataSet com linhas de uma consulta feita em um banco de dados SQL

http://www.macoratti.net/

C# - ADO .NET para iniciantes


Server. (Se acessar um banco de dados Access voc usa um objeto OledbDataAdapter). Uma vez populadas voc pode realizar alteraes no DataSet, incluindo e excluindo linhas (rows), efetuando ordenaes, etc, e ento usar o objeto SqlDataAdpater novamente para refletir estas alteraes no banco de dados original usando um comando SQL apropriado como UPDATE, DELETE, INSERT.

46

Os dados esto contidos essencialmente no objeto DataTable mas a coleo DataRelationCollection que permite que voc a hierarquia da tabela. As tabelas esto contidas na coleo DataTableCollection que acessada atravs da propriedade Tables.

Lembre-se que ao usar um DataSet voc esta trabalhando com uma cpia dos dados em memria e por isso qualquer atualizao feita nos dados tem que ser refletida na fonte de dados de origem, de outra forma , se voc no atualizar os dados originais com as alteraes a fonte de dados no ser atualizada. Os dados internos contidos em um DataSet so mantidos no formato XML e a estrutura do DataSet definida pelo XSD (XML Schema Definition Language), ou seja, XML e DataSet esto intimamente ligados.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


A principal caracterstica do DataSet totalmente desconectado, voc pode usar um DataSet para armazenar dados de um banco de dados e pode tambm mover os dados de um DataSet para um banco de dados, mas o prprio DataSet no faz conexo alguma com o banco de dados, ele nem mesmo tem um objeto para realizar tal conexo . Resumindo as funcionalidades do DataSet: - Funciona como um cache in-memory, ou seja, voc ter as tabelas disponveis para uso, podendo fazer acesso aleatrio aos registros, inserir, alterar e deletar registros da tabela; - Opera desconectado do banco, assim , voc trabalha com os registros sem usar uma conexo do banco de dados; - Opera com n tabelas por vez, e permite a possibilidade de relacionamento entre as mesmas alm de funcionalidades como ordenao, filtragem, etc. Nota: A conexo utilizada pelo DataSet no necessita ser aberta e/ou fechada manualmente. Ao chamar o mtodo Fill do DataAdapter a conexo aberta, so coletados os dados solicitados e a conexo fechada. (No caso do DataReader voc tem que abrir e fechar)
47

A classe SqlDataAdapter
A classe SqlDataAdapter serve como uma ponte entre o DataSet e o banco de dados SQL Server para retornar e salvar dados. O SqlDataAdapter fornece esta ponte da seguinte forma:
1. O mtodo Fill que altera os dados no DataSet para coincidir com os dados da fonte de dados; Quando o mtodo Fill executado ele cria as colunas e tabelas necessrias para os dados retornados se eles no existirem; a informao da chave primria no includa a menos que a propriedade MissingSchemaAction for definida para AddWithKey. 2. O mtodo Update o qual altera os dados na fonte de dados para coincidir com os dados do DataSet usando o comando T-SQL apropriado contra a fonte de dados. A atualizao feita da seguinte forma: para cada linha inserida, modificada e deletada o mtodo Update determina o tipo de alterao que foi realizada (Insert, Update ou Delete) e dependendo do tipo de alterao, o comando Insert, Update ou Delete executado para propagar a linha modificada para a fonte de dados.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


De forma geral em uma implementao com mais de uma camada os passos para criar e atualizar um DataSet e em seguida atualizar os dados originais so:
1. 2. 3. 4. 5. 6. Construir e preencher cada DataTable no DataSet com os dados da fonte de dados usando um objeto DataAdapter; Alterar os dados nos objetos DataTable individuais pela incluso, atualizao ou excluso de objetos DataRow; Invocar o mtodo GetChanges para criar um segundo DataSet que representa somente as alteraes feitas; Chamar o mtodo Update do DataAdapter passando o segundo DataSet como um argumento; Invocar o mtodo Merge para mesclar as alteraes a partir do segundo DataSet no primeiro; Invocar o mtodo AcceptChanges no DataSet ou invocar o mtodo RejectChanges para cancelar as alteraes; 48

Criando um DataSet
Todos as classes relacionadas como DataSet, DataAdapter, DataTable, DataRow etc esto disponveis no namespace System.Data. A primeira coisa a fazer definir o namespace que pode ser feito da seguinte forma:
Em uma pgina ASP .NET
Em um arquivo C#:

<%@ Import Namespace="System.Data" %> using System.Data;

Para criar um objeto DataSet voc usa a seguinte sintaxe: DataSet <nomedoDataSet> = new DataSet();

DataSet dsClientes = new DataSet();


Observe que o construtor DataSet no requer nenhum parmetro, porm existe um construtor sobrecarregado que aceita uma string para o nome do DataSet o qual usado se voc deseja serializar os dados para o formato XML.

Criando um SqlDataAdater
http://www.macoratti.net/

C# - ADO .NET para iniciantes


Um SqlDataAdapter trata os comandos SQL e o objeto Connection para leitura e escrita de dados. Para inicializar um SqlDataAdaptar informamos um comando SQL e um objeto Connection que definia conexo com a fonte de dados:
49

SqlDataAdapter daClientes = new SqlDataAdapter("Select codigo, Nome from Clientes", conexaoBD);


No cdigo acima criamos um novo SqlDataAdpater , daClientes onde o comando SQL Select especifica que iremos ler os dados para o DataSet e o objeto Connection , conexaoBD, que dever j ter sido iniciado, mas no aberto. responsabilidade do SqlDataAdpater abrir e fechar a conexo durante a chamada dos mtodos Fill e Update. Para usar comandos SQL para incluir, atualizar e deletar temos duas maneiras distintas:

Usando as propriedades da classe SqlDataAdapter; Usando o SqlCommandBuilder;

O objeto SqlDataAdapter no gera automaticamente comandos Transact-SQL necessrios para ajustar as alteraes feitas a um DataSet associado com uma instncia do SQL Server. Voc pode , no entanto, criar um objeto SqlCommandBuilder para gerar automaticamente estes comandos para atualizaes em uma tabela nica . Veja abaixo um exemplo : SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daClientes);

O comando SqlCommandBuilder instanciado usando como parmetro a instncia do SqlDataAdatper, no caso daClientes, dessa forma o SqlCommandBuilder ir ler os comandos SQL e atribuir os novos comandos as propriedades Insert, Update e Delete do SqlDataAdapter. o SqlCommandBuilder tem a limitao de gerar os comandos apenas para uma nica tabela, se voc precisar trabalhar com mais de uma tabela ou usar um Join ter que usar as propriedades da classe SqlDataAdapter.

http://www.macoratti.net/

C# - ADO .NET para iniciantes Preenchendo um DataSet


Depois de criar instncias de um DataSet e de um SqlDataAdpater voc precisa preencher o DataSet usando o mtodo Fill do SqlDataAdapter:
50

daClientes.Fill(dsClientes, "Clientes");
O mtodo Fill , usa dois parmetros :

um DataSet - O DataSet precisa ser instanciado antes voc tentar preench-lo com dados; o nome de uma tabela - A tabela que ser criada no DataSet. Voc pode usar qualquer nome.

Nota: O mtodo Fill possui uma sobrecarga que usa somente o DataSet; neste caso a tabela criada ter um nome padro de "table1" para a primeira tabela.

Exemplos de utilizao de um DataSet


Recursos usados nos exemplos a seguir:

banco de dados Northwind.mdf do SQL Server 2005 Express Edition ; conexo definida no meu Servidor SQL Server MAC\SQLEXPRESS (para adaptar o exemplo para o seu caso mude a string de conexo); Visual C# 2008 Express Edition;

1- Usando um DataSet com SqlDataAdapter para selecionar dados no SQL Server


Neste exemplo estamos apenas acessando o SQL Server 2005 e selecionando dados da tabela Products. Como no estamos alterando os dados no precisamos usar o objeto SqlCommandBuilder para preparar o DataSet para realizar tais operaes. - Crie um novo projeto no Visual C# com o nome uDataSet1 do tipo Windows Forms Application ;

http://www.macoratti.net/

C# - ADO .NET para iniciantes


- No formulrio padro form1.cs inclua um controle DataGridView - gdvProdutos e um controle Button - btnPreencheGrid ; - Defina o namespace System.Data.SqlClient - Declare as variveis objetos que sero usadas no projeto: //define os objetos SqlConnection, DataSet //SqlDataAdapter e o nome da tabela private SqlConnection conn; private SqlDataAdapter daProdutos; private DataSet dsProdutos; private const string tabela = "Produtos"; - Inclua o seguinte cdigo no evento Click do controle Button: private void btnPreencheGrid_Click(object sender, EventArgs e) {
//chama a rotina para iniciar o dataset IniciaDados();

51

//exibe o dataset no controle datagridview - dgvProdutos dgvProdutos.DataSource = dsProdutos; dgvProdutos.DataMember = tabela; } - A rotina IniciaDados() possui o seguinte cdigo: // definio dos objetos dataset, sqldataadapter e sqlcommandbuilder public void IniciaDados() {

http://www.macoratti.net/

C# - ADO .NET para iniciantes


try { //instancia uma nova conexo usando a string de conexo //com o banco de dados Northwind do SQL Server 2005 Express conn = new SqlConnection("Server=MAC\\SQLEXPRESS;DataBase=Northwind;Integrated Security=SSPI"); // 1. instancia um novo DataSet dsProdutos = new DataSet(); // 2. inicia o SqlDataAdapte passando o comando SQL para selecionar codigo e nome // do produto e a conexo com o banco de dados daProdutos = new SqlDataAdapter("Select ProductID, ProductName from Products", conn); // 3. preenche o dataset daProdutos.Fill(dsProdutos, tabela); } catch(Exception ex) { //se houver erro exibe a mensagem MessageBox.Show(ex.Message);
} }

52

O resultado obtido pode ser visto na figura abaixo:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


53

2- Usando um DataSet com SqlDataAdapter para incluir, alterar e excluir dados no SQL Server
Vamos usar o exemplo anterior e incluir no formulrio mais 3 botes de comandos para incluir, alterar e excluir dados da tabela Products;

http://www.macoratti.net/

C# - ADO .NET para iniciantes


54

Incluir - btnIncluir

Alterar - btnAlterar Excluir- btnExcluir

Vamos definir a varivel do codigo como do tipo String que ir armazenar o cdigo do produto. private String codigo = ""; A seguir temos o cdigo do boto - Listar Dados - que aps obter a lista de produtos habilita os botes de comando:
private void btnPreencheGrid_Click(object sender, EventArgs e) { IniciaDados(); //exibe o dataset no controle datagridview - dgvProdutos dgvProdutos.DataSource = dsProdutos; dgvProdutos.DataMember = tabela;

http://www.macoratti.net/

C# - ADO .NET para iniciantes


btnIncluir.Enabled = true; btnExcluir.Enabled = true; btnAlterar.Enabled = true; }

55

No evento Click do boto Incluir temos o cdigo que inclui um novo registro na tabela Products. Estamos usando o mtodo NewRow() e incluindo uma nova linha na tabela; Estou incluindo um produto com o nome Macoratti_ Estamos usando o procedimento bsico para incluir dados em um dataset : criando uma nova linha e em seguida adicionando a coleo DataRow do DataTable no DataSet No nosso caso estamos fazendo isso em um DataSet no tipado chamando o mtodo NewRow para criar uma nova linha vazia; esta linha herda a estrutura da coluna da coleo DataColumnCollection. Em seguida inclumos(add) a linha na coleo de linhas e atualizamos(update) o dataset.
private void btnIncluir_Click(object sender, EventArgs e) { daProdutos = new SqlDataAdapter("SELECT ProductID, ProductName FROM Products", conn); SqlCommandBuilder cmdbldr = new SqlCommandBuilder(daProdutos); dsProdutos = new DataSet(); daProdutos.Fill(dsProdutos); DataRow registro = dsProdutos.Tables[0].NewRow(); registro["ProductName"] = "Macoratti_"; dsProdutos.Tables[0].Rows.Add(registro); //atualiza o dataset daProdutos.Update(dsProdutos); MessageBox.Show("Registro incluido."); }

O cdigo do evento Click do boto Alterar visto a seguir.

http://www.macoratti.net/

C# - ADO .NET para iniciantes


- No cdigo obtemos o valor do cdigo do produto a partir da linha selecionada no DataGridView e armazenamos na varivel codigo; - Em seguida verificamos se o codigo possui um valor vlido; - Usamos o mtodo Find do DataTable para localizar o registro com o cdigo obtido e atualizamos o nome do produto com um sinal de #;
private void btnAlterar_Click(object sender, EventArgs e) { daProdutos = new SqlDataAdapter("SELECT ProductID, ProductName FROM Products order by ProductID", conn); SqlCommandBuilder cmdbldr = new SqlCommandBuilder(daProdutos); dsProdutos = new DataSet(); daProdutos.Fill(dsProdutos); DataColumn[] chave = new DataColumn[1]; chave[0] = dsProdutos.Tables[0].Columns[0]; dsProdutos.Tables[0].PrimaryKey = chave; codigo = dgvProdutos.CurrentRow.Cells["ProductID"].Value.ToString(); if (codigo != null || !codigo.Equals("")) { DataRow registro = dsProdutos.Tables[0].Rows.Find(codigo); registro["ProductName"] = registro["ProductName"] + " # "; daProdutos.Update(dsProdutos); MessageBox.Show("Registro alterado."); } else { MessageBox.Show("Registro no localizado."); } }

56

O cdigo do evento Click do boto Excluir visto a seguir. - No cdigo obtemos o valor do cdigo do produto a partir da linha selecionada no DataGridView e armazenamos na varivel codigo;

http://www.macoratti.net/

C# - ADO .NET para iniciantes


- Em seguida verificamos se o codigo possui um valor vlido; - Usamos o mtodo Find do DataTable para localizar o registro com o cdigo obtido; - Para excluir usamos o mtodo Delete;
private void btnExcluir_Click(object sender, EventArgs e) { daProdutos = new SqlDataAdapter("SELECT ProductID, ProductName FROM Products order by ProductID", conn); SqlCommandBuilder cmdbldr = new SqlCommandBuilder(daProdutos); dsProdutos = new DataSet(); daProdutos.Fill(dsProdutos); DataColumn[] chave = new DataColumn[1]; chave[0] = dsProdutos.Tables[0].Columns[0]; dsProdutos.Tables[0].PrimaryKey = chave; codigo = dgvProdutos.CurrentRow.Cells["ProductID"].Value.ToString(); if (codigo != null || !codigo.Equals("")) { DataRow registro = dsProdutos.Tables[0].Rows.Find(codigo); registro.Delete(); daProdutos.Update(dsProdutos); MessageBox.Show("Registro excluido."); } else { MessageBox.Show("Registro no localizado."); } }

57

O resultado obtido pode ser visto na figura abaixo:

http://www.macoratti.net/

C# - ADO .NET para iniciantes


58

Com isso mostrei os procedimentos bsicos de como atualizar um dataset no tipado usando ADO .NET; Pegue o projeto completo aqui : uDataSet1.zip

No prximo artigo irei falar mais um pouco sobre dataset , mais particularmente dos datasets tipados

http://www.macoratti.net/