Você está na página 1de 17

2): Modelo

27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

Felipe Pimentel

Aprendendo C# (Parte 2): Modelo Desconectado de


Acesso ao Banco de Dados

1. Início

Dando continuidade à nossa série de artigos, neste post vamos mostrar alguns exemplos de como
podemos estabelecer uma conexão e manipular dados no modelo desconectado. No artigo
anterior já discutimos as vantagens e desvantagens deste modelo, vide url:

http://fpimentel88.wordpress.com/2009/01/18/aprendendo-c-parte-1-acessando-um-banco-sql-
server-2005-com-adonet/ (http://fpimentel88.wordpress.com/2009/01/18/aprendendo-c-parte-1-
acessando-um-banco-sql-server-2005-com-adonet/)

2. Objetos utilizados no modelo desconectado

A idéia do modelo desconectado é bastante simples: Recuperar dados do banco para a memória, e
manipulá-los sem ser necessário fazer novas requisições à database.

Para fazer isto, nós utilizamos algumas classes já discutidas no post anterior, que são eles:

1. SqlConnection – Objeto responsável por saber e mantér conexão com o banco de dados.
2. DataSet – Estrutura complexa que irá representar nossos dados em memória.
3. SqlDataAdapter – É uma ponte entre o Dataset e o SqlConnection. É o objeto responsável pelo
fluxo de dados entre a memória e o banco, e vice-versa.

3. Começando a codificar

O fluxo básico de qualquer modelo desconectado é sempre o mesmo: Resgata Dados –> Manipula
dados –> Sincroniza dados com banco.

Nesses nossos exemplos iremos utilizar a mesma estrutura do banco que o post anterior, ou seja,
as nossas operações serão em cima de nossa tabela “Pessoa”.
…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 1/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

Caso não tenha acompanhado o primeiro post, volto à repetir: deem, nem que seja rapidamente,
uma lida no mesmo.

3.1 Resgatando dados do banco

Vamos ser bastante direto nesse post, enrolando menos e fazendo mais exercícios práticos. Logo, o
nosso código para resgatar valores para a memória é:

1: public static void Main(string[] args)

2: {

3: string connectionString = @"Data Source=.\SQL;Initial Catalog=

4: string query = @"SELECT * FROM Pessoa";

5:

6: //

7: //Instância objeto que irá manipular e manter conexão com banc

8: //

9: SqlConnection conn = new SqlConnection(connectionString);

10:

11: //

12: // Objeto que irá armazenar dados vindos do banco

13: //

14: DataSet ds = new DataSet();

15:

16: //

17: //Objeto que servirá como ponte de uma determinada conexão e u

18: //

19: SqlDataAdapter adapter = new SqlDataAdapter(query, conn);

20:

21: //

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 2/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

22: //Atraves da ponte, preencho o dataset com dados buscados no b

23: //

24: adapter.Fill(ds);

25: }

Viram como é simples? Pois é. Seis linha de código e já temos os dados em mãos. Acho que não
tem nem o que explicar desse código, pois creio que todos entenderam que o SqlDataAdapter
funciona como uma ponte de dados entre banco e memória.

- “Opa Felipe. Mas esse seu código vai dar erro!!! Você esqueceu de abrir a conexão!!!”

Calma meus caros leitores!!!

Ao se utilizar o DataAdapter não precisamos ficar preocupado em abrir e fechar conexões. Pois,
por debaixo dos panos o adapter irá abrir a conexão, logo após irá executar o comando e em
seguida irá fechar a conexão com o banco, sendo tudo isso invisível ao usuário.

Um fato importante no SqlDataAdapter é que após executar o comando, ele deixa a conexão no
mesmo estado que ela se encontrava. Ou seja, caso a conexão se encontrasse aberta ao executar a
instrução “adapter.Fill(ds)” , o SqlDataAdapter permaneceria com a mesma aberta ao final do
comando.

- “Humm… Certo! Entendi! Trouxemos os dados do banco para o dataset, mas como consigo
listá-los?”

Como eu disse, o DataSet tem uma estrura semelhante ao banco, com tabelas, linhas, colunas. Da
seguinte maneira:

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 3/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

(http://fpimentel88.files.wordpress.com/2009/01/screenshot014.jpg)

Sabendo disso, podemos exibir nossos dados pegando a nossa primeira tabela do DataSet que é a
tabela de pessoa, em seguida podemos iterar nas linhas da mesma, da seguinte maneira:

1: public static void Main(string[] args)

2: {

3: string connectionString = @"Data Source=.\SQL;Initial Catalog=

4: string query = @"SELECT * FROM Pessoa";

5:

6: //

7: //Instância objeto que irá manipular e manter conexão com banc

8: //

9: SqlConnection conn = new SqlConnection(connectionString);

10:

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 4/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

11: //

12: // Objeto que irá armazenar dados vindos do banco

13: //

14: DataSet ds = new DataSet();

15:

16: //

17: //Objeto que servirá como ponte de uma determinada conexão e u

18: //

19: SqlDataAdapter adapter = new SqlDataAdapter(query, conn);

20:

21: //

22: //Atraves da ponte, preencho o dataset com dados buscados no b

23: //

24: adapter.Fill(ds);

25:

26: //

27: // Pega a primeira tabela do dataset, que é a tabela de pessoa

28: //

29: DataTable dtPessoa = ds.Tables[0];

30:

31: //

32: // iteração nas linhas da tabela de pessoa.

33: //

34: foreach (DataRow row in dtPessoa.Rows)

35: {

36: //

37: //exibição dos dados no console

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 5/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

38: //

39: Console.WriteLine(row["id"] + " " + row["nome"] + " "

40: }

41: }

Observe que as linhas estam indexadas. Ou seja, ao fazer “row[‘nome’]”, estou pegando o
nome de uma determinada linha.

3.2 Inserindo valores no DataSet

Como falamos anteriormente, os dados serão manipulados em memória, ou seja, iremos adicionar
uma nova pessoa diretamente na DataTable.

- “E como sincronizo as alterações que fiz no DataSet com o meu banco?”

Isso é bastante simples de se fazer. Básicamente, o objeto adapter possui um método chamado
Update, que recebe um DataSet como parâmetro, e com base nesse DataSet o Adapter faz as
modificações necessárias.

(http://fpimentel88.files.wordpress.com/2009/01/screenshot0011.jpg)

-“Certo! Mas como o SqlDataAdapter sabe as modificações que eu fiz no DataSet?”

A resposta para essa pergunta, também é simples. Cada DataRow possui uma propriedade
chamada “RowState” e de acordo com seu valor o SqlDataAdapter irá tomar as providências
necessárias na hora da sincronização com o banco. A propriedade “RowState” pode assumer os
seguintes valores:

1. Added – Quando a linha é adicionada em uma DataRowCollection.


2. Deleted - A linha fica neste estado quando é chamado o método “Delete()” da mesma.
3. Detached – Considero este valor da enumeração o mais complicado de se entender, mas isso
não quer dizer que é impossível. Básicamente, a linha fica neste estado quando ela não
pertende à nenhum DataRowCollection, ou seja, quando acabamos de criar uma linha e ela
ainda não foi adicionada à estrutura alguma, ou quando removemos a linha de uma
DataRowCollection.A linha se encontra neste estado, por exemplo, no seguinte caso:“DataRow
dr = ds.Tables[0].NewRow();”Neste caso, temos a linha (dr), mas que não pertence a estrutura

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 6/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

alguma. Ela passará para o estado de “added” quando eu fizer


isto:ds.Tables[0].Rows.Add(dr);Agora sim a linha pertênce a primeira tabela de meu DataSet.
4. Modified – Linha fica neste estado quando é modificado.
5. Unchanged – Valor default das linhas quando veem do banco.

- “Que ótimo!!! Então quer dizer que só preciso chamar o Update() e pronto?”

Bem caros leitores, não é bem assim. Nem tudo é mar de rosas.

Antes de chamarmos o método Update() devemos configurar o nosso DataAdapter para que ele
aceite todos os comando (INSERT, UPDATE, DELETE).

Isso precisa ser feito, porque quando chamamos o método Update, ele sabe o que deve fazer com
cada linha. Ele sabe que deve inserir um linha, remover outra e talvez atualizar outra, por
exemplo. Mas o SqlDataAdapter por se só não sabe como fazer isto. Ou seja, ele sabe o que
precisa fazer, mas não como fazer. É por isto que devemos configurar cada comando. E isto é
feito da seguinte maneira:

1: static void ConfiguraDataAdapter(SqlDataAdapter adapter, SqlConnection co

2: {

3: string insertQuery = "INSERT INTO Pessoa (nome, dataNascimento

4: SqlCommand cmd = new SqlCommand(insertQuery, conn);

5: cmd.Parameters.Add("nome", SqlDbType.NVarChar, 100, "nome"

6: cmd.Parameters.Add("dataNascimento", SqlDbType.SmallDateTime,

7: cmd.Parameters.Add("email", SqlDbType.NVarChar, 50, "email"

8: cmd.Parameters.Add("sexo", SqlDbType.NChar, 1, "sexo");

9: adapter.InsertCommand = cmd;

10: }

Este método é o respónsavel por configurar os comandos do SqlDataAdapter (Observe que fiz
apenas o insert, os outros comandos deixo como atividade para vocês);

Então com base em tudo que conversarmos, vamos finalmente inserir uma nova linha em nossa
DataRowCollection e em seguida sincronizar com o banco. Nosso código final ficará da seguinte
maneira:

1: static Pessoa GetPessoa()

2: {

3: Pessoa pessoa = new Pessoa();


…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 7/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

4: Console.WriteLine("Nome ");

5: pessoa.Nome = Console.ReadLine();

6: Console.WriteLine("Email ");

7: pessoa.Email = Console.ReadLine();

8: Console.WriteLine("Sexo (M ou F) ");

9: pessoa.Sexo = Convert.ToChar(Console.ReadLine());

10: Console.WriteLine("Data de Nascimento");

11: pessoa.DataNascimento = Convert.ToDateTime(Console.ReadLine());

12: return pessoa;

13: }

14:

15: static void ConfiguraDataAdapter(SqlDataAdapter adapter, SqlConnect

16: {

17: //

18: // query de insert

19: //

20: string insertQuery = "INSERT INTO Pessoa (nome, dataNascimento,

21:

22: //

23: // Criação do comando

24: //

25: SqlCommand cmd = new SqlCommand(insertQuery, conn);

26:

27: //adiciona parametros

28: cmd.Parameters.Add("nome", SqlDbType.NVarChar, 100, "nome");

29: cmd.Parameters.Add("dataNascimento", SqlDbType.SmallDateTime, 1

30: cmd.Parameters.Add("email", SqlDbType.NVarChar, 50, "email"

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 8/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

31: cmd.Parameters.Add("sexo", SqlDbType.NChar, 1, "sexo");

32:

33: //informa quem vai ser o comando do insert do SqlDataAdapter

34: adapter.InsertCommand = cmd;

35: }

36:

37: public static void Main(string[] args)

38: {

39: string connectionString = @"Data Source=.\SQL;Initial Catalog=E

40: string query = @"SELECT * FROM Pessoa";

41:

42: //

43: //Instância objeto que irá manipular e manter conexão com banco

44: //

45: SqlConnection conn = new SqlConnection(connectionString);

46:

47: //

48: // Objeto que irá armazenar dados vindos do banco

49: //

50: DataSet ds = new DataSet();

51:

52: //

53: //Objeto que servirá como ponte de uma determinada conexão e um

54: //

55: SqlDataAdapter adapter = new SqlDataAdapter(query, conn);

56:

57:

9/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

58: //

59: // Chama método que irá configurar todos os comando do adapter

60: //

61: ConfiguraDataAdapter(adapter, conn);

62:

63: //

64: //Atraves da ponte, preencho o dataset com dados buscados no ba

65: //

66: adapter.Fill(ds);

67:

68: //

69: // Pega a primeira tabela do dataset, que é a tabela de pessoa

70: //

71: DataTable dtPessoa = ds.Tables[0];

72:

73: //

74: // Cria linha de acordo com esquema de linhas da tabela "dtPess

75: // NESSE INSTANTE A LINHA SE ENCONTRA NO ESTADO DE "Detached"

76: //

77: DataRow drNewPessoa = dtPessoa.NewRow();

78:

79: //

80: // Preenche linha com dados da pessoa

81: //

82: Pessoa pessoa = GetPessoa();

83: drNewPessoa["email"] = pessoa.Email;

84: drNewPessoa["dataNascimento"] = pessoa.DataNascimento;

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 10/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

85: drNewPessoa["nome"] = pessoa.Nome;

86: drNewPessoa["sexo"] = pessoa.Sexo;

87:

88: //

89: // Adiciono nova linha de Pessoa a tabela de pessoa

90: // nesse momento a linha se encontra no estado "Added"

91: //

92: dtPessoa.Rows.Add(drNewPessoa);

93:

94: //

95: // Sincronização com o banco

96: //

97: adapter.Update(ds);

98:

99: Console.WriteLine("Sincronização realizada com sucesso!!!");

100: }

Então agora o noso código já adiciona registros no banco. Não vou fazer as próximas operações,
espero que vocês façam. Qualquer dúvidam podem comentar, ou então entrar em contato por
email.

4. Finalizando

Para finalizar vamos fazer um exemplo do que podemos fazer manipulando os estados das
linhas.

Sabendo que a DataRow possui um método chamado “AcceptChanges()” que básicamente


coloca o estado da linha em “Unchanged”. O que você acha que vai acontecer se eu fizer uma
série de alterações em linhas de uma DataTable, mas antes de dar um Update no
SqlDataAdapter, eu der um AcceptChanges em todas as linhas?

Isso mesmo!!! Nenhuma linha será atualizada, pois o SqlDataAdapter só irá modificar no banco
as linhas que estiverem com valores diferentes de “Unchanged”. Para vocês verem que isso
acontece, rodem o seguinte código:

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 11/17
2): Modelo Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

1: static Pessoa GetPessoa()

2: {

3: Pessoa pessoa = new Pessoa();

4: Console.WriteLine("Nome ");

5: pessoa.Nome = Console.ReadLine();

6: Console.WriteLine("Email ");

7: pessoa.Email = Console.ReadLine();

8: Console.WriteLine("Sexo (M ou F) ");

9: pessoa.Sexo = Convert.ToChar(Console.ReadLine());

10: Console.WriteLine("Data de Nascimento");

11: pessoa.DataNascimento = Convert.ToDateTime(Console.ReadLine());

12: return pessoa;

13: }

14:

15: static void ConfiguraDataAdapter(SqlDataAdapter adapter, SqlConnect

16: {

17: //

18: // query de insert

19: //

20: string insertQuery = "INSERT INTO Pessoa (nome, dataNascimento,

21:

22: //

23: // Criação do comando

24: //

25: SqlCommand cmd = new SqlCommand(insertQuery, conn);

26:

27: //adiciona parametros

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 12/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

28: cmd.Parameters.Add("nome", SqlDbType.NVarChar, 100, "nome");

29: cmd.Parameters.Add("dataNascimento", SqlDbType.SmallDateTime, 1

30: cmd.Parameters.Add("email", SqlDbType.NVarChar, 50, "email"

31: cmd.Parameters.Add("sexo", SqlDbType.NChar, 1, "sexo");

32:

33: //informa quem vai ser o comando do insert do SqlDataAdapter

34: adapter.InsertCommand = cmd;

35: }

36:

37: public static void Main(string[] args)

38: {

39: string connectionString = @"Data Source=.\SQL;Initial Catalog=E

40: string query = @"SELECT * FROM Pessoa";

41:

42: //

43: //Instância objeto que irá manipular e manter conexão com banco

44: //

45: SqlConnection conn = new SqlConnection(connectionString);

46:

47: //

48: // Objeto que irá armazenar dados vindos do banco

49: //

50: DataSet ds = new DataSet();

51:

52: //

53: //Objeto que servirá como ponte de uma determinada conexão e um

54: //

13/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

55: SqlDataAdapter adapter = new SqlDataAdapter(query, conn);

56:

57:

58: //

59: // Chama método que irá configurar todos os comando do adapter

60: //

61: ConfiguraDataAdapter(adapter, conn);

62:

63: //

64: //Atraves da ponte, preencho o dataset com dados buscados no ba

65: //

66: adapter.Fill(ds);

67:

68: //

69: // Pega a primeira tabela do dataset, que é a tabela de pessoa

70: //

71: DataTable dtPessoa = ds.Tables[0];

72:

73: //

74: // Cria linha de acordo com esquema de linhas da tabela "dtPess

75: // NESSE INSTANTE A LINHA SE ENCONTRA NO ESTADO DE "Detached"

76: //

77: DataRow drNewPessoa = dtPessoa.NewRow();

78:

79: //

80: // Preenche linha com dados da pessoa

81: //

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 14/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

82: Pessoa pessoa = GetPessoa();

83: drNewPessoa["email"] = pessoa.Email;

84: drNewPessoa["dataNascimento"] = pessoa.DataNascimento;

85: drNewPessoa["nome"] = pessoa.Nome;

86: drNewPessoa["sexo"] = pessoa.Sexo;

87:

88: //

89: // Adiciono nova linha de Pessoa a tabela de pessoa

90: // nesse momento a linha se encontra no estado "Added"

91: //

92: dtPessoa.Rows.Add(drNewPessoa);

93:

94: drNewPessoa.AcceptChanges();

95:

96: //

97: // Sincronização com o banco

98: //

99: adapter.Update(ds);

100:

101: Console.WriteLine("Sincronização realizada com sucesso!!!");

102: }

Note que a linha jamais será adicionada, pois estou dando um “AcceptChanges()” antes de dar
um “Update()” no Adapter!!!

Para baixar o código de exemplo, acesse o seguinte link:

http://cid-2d6d3503299ba131.skydrive.live.com/self.aspx/Artigos/AcessoBancoDadosII.rar
(http://cid-2d6d3503299ba131.skydrive.live.com/self.aspx/Artigos/AcessoBancoDadosII.rar)

Espero ter ajudado. Qualquer coisa comentem.

Essa entrada foi publicada em 0, 20 \20\UTC janeiro \20\UTC 2009 às 4:51 am e arquivada em
…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 15/17
2): Modelo
27/10/12
Desconectado de Acesso ao Banco de Dados « Felipe Pimentel

c#. Você pode acompanhar qualquer resposta para esta entrada através do feed RSS 2.0. Você
pode deixar uma resposta, ou trackback do seu próprio site.

8 respostas para Aprendendo C# (Parte 2): Modelo


Desconectado de Acesso ao Banco de Dados

1. Analisando e melhorando a performance em aplicações ASP.NET (Parte 1) « Felipe Pimentel


disse:
janeiro 20, 2009 às 6:49 am
[...] eu já postei um artigo hoje ( http://fpimentel88.wordpress.com/2009/01/20/aprendendo-c-
parte-2-modelo-desconectado-de-acesso-ao-ba… ser preve nessa primeira parte. O foco nesse
primeiro post será falar um pouco dos problemas que [...]

2. Ronaldo disse:
março 2, 2009 às 11:25 am
Parabéns Felipe, já fazia algum tempo que eu procurava entender este assunto, mas não
conseguia achar um artigo claro como este seu, parabéns continue escrevendo!

3. estrelinha disse:
março 11, 2009 às 11:08 am
Filipe os meus mais sinceros parabém por esta sua iniciativa.

porque não postar um exemplo onde demostre uma aplicação windows Forms aplications..

tipo criar um formulário e carregar em combobox os dados de uma coluna de uma tabela da
base dados estudobog.

humm… e porque não?

;)

4. Marco Lima disse:


janeiro 19, 2010 às 7:24 pm
Obrigado kra!! Ta me ajundando esses posts.

5. Cesar Barreto disse:


agosto 11, 2010 às 9:00 pm
Muito obrigado pela ajuda. Estou tendo dificuldades em fazer a conexao no VS com o SQL
Express. Você poderia mostrar como fazê-lo? Conexão e inserção de dados passo a passo ?
Obrigado !

6. Alane disse:
setembro 9, 2010 às 10:14 pm
Muito bacana, é bom termos conceitos detalhados de cada objeto do ADO e .NET, as vezes
temos o conjunto em funcionamento, mas não sabemos teoricamente como as coisas
funcionam internamente. Muito bom mesmo !

…wordpress.com/…/aprendendo-c-parte-2-modelo-desconectado-de-acesso-ao-banco-de-dados/ 16/17
7. Rhone disse:
abril 18, 2011 às 1:11 pm
Bom dia.

Estou com duvidas a respeito de dados desconectados e gostaria de saber de vc pode me


ajudar.
1-Posso ler uma base com por exemplo de 1 milhão ou mais de registros?
2-Se tiver 30,40 ou mais estações acessando e atualizando a base? O banco controla isso tudo?

8. Ricardo disse:
abril 23, 2011 às 1:38 pm
Muito bom o artigo!
Continue escrevendo ..
[]s

Tema: Contempt por Vault9 .


Blog no WordPress.com.

Você também pode gostar