ADO.NET 2.0 - DataTable e DataSet


 

Como prometido , neste artigo vou falar um pouco das novas características da ADO.NET 2.0. É claro que não vai dar para esgotar o assunto, vou primeiro apresentar as novidades mais relevantes apresentando-as e a seguir, em artigos futuros, vendo sua implementação prática.

 

Com o advento da versão da ADO.NET, como não podia deixar de ser, a Microsoft promete  melhorias no desempenho e na eficiência das aplicações que usarem as novas características. Dentre as muitas classes da .NET Framework, a classe  DataSet e a classe DataTable possui uma importância especial. Por esta razão vou começar tentando mostrar o que existe de novo em relação a estas classes.

 

Um DataTable melhor e mais independente

 

Apenas para localizar os programadores VB que estão migrando da ADO para ADO.NET, podemos dizer que o DataTable esta para o objeto Recordset da ADO.  Como o DataTable se comporta como um conjunto de linhas e colunas é uma das principais classes usadas armazenar dados. Dai já deu para sentir a sua importância quando o assunto é acesso aos dados.

 

Se você conhecia o DataTable das versões anteriores da ADO.NET ( 1.0 e 1.1) e teve momentos de frustração quanto tentou realizar alguma tarefa com o DataTable que acabava exigindo a presença de um DataSet, saiba que isto mudou. O DataTable praticamente saiu da berlinda e ganhou novos métodos.

 

As operações com o DataTable e DataSet ganharam em desempenho. Com um novo motor de indexação as operações com grande volume de dados ficou mais rápida nas inclusões, atualizações e exclusões de dados devido as operações realizadas pelos métodos Fill e Merge terem sido otimizadas.

 

Além disto o DataTable ganhou novos métodos e propriedades:

Merge - método que permite mesclar dois objetos DataTable.
 

Antes da versão 2.0 do ADO.NET você podia mesclar dois DataTables mas tinha que "pedir a permissão" para o DataSet. Vejamos como isto era feito e como pode ser feito agora:

 

- Estou usando o SGBD MSDE (ainda não instalei o SQL Server Express) onde vou acessar a tabela Customers do banco de dados Northwind

- Estou usando o VS.NET 2003 e o Visual Basic 2005 Express para testes do código

 

1- Como era no ADO.NET 1.1  usando VS.NET 2003

 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        'monta a instrução SQL e define a string de conexão com o MSDE(instalado na minha maquina)
        Dim strSQL As String = "SELECT * FROM Customers"
        Dim cnStr As String = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;User ID=sa;password=;_
                                       Data Source=MACORATI\VSDOTNET"
        Dim cn As SqlConnection = New SqlConnection(cnStr)
        Try
            'abre a conexão com o MSDE/Northwind
            cn.Open()

            'define o comando SQL o DataAdapter e cria o DataTable
            Dim cmd As SqlCommand = New SqlCommand(strSQL, cn)
            Dim da As SqlDataAdapter = New SqlDataAdapter(cmd)
            Dim dtbl_Clientes1 As DataTable = New DataTable("Customers")

            'preenche o DataTable
            da.Fill(dtbl_Clientes1)

            'defina a coluna como chave primaria 
            dtbl_Clientes1.PrimaryKey = New DataColumn() {dtbl_Clientes1.Columns("CustomerID")}
            'faz uma copia da estrutura do primeiro DataTable
            Dim dtbl_Clientes2 As DataTable = dtbl_Clientes1.Clone

            'cria a primeira linha no segundo DataTable
            Dim linha1 As DataRow = dtbl_Clientes2.NewRow
            linha1("CustomerID") = "ALFKI"
            linha1("CompanyName") = "JcmSoft Inc."
            dtbl_Clientes2.Rows.Add(linha1)

            'cria a segunda linha no segundo DataTable
            Dim linha2 As DataRow = dtbl_Clientes2.NewRow
               linha2("CustomerID") = "JCM"
               linha2("CompanyName") = "Macoratti.net"
            dtbl_Clientes2.Rows.Add(linha2)

            'cria o dataset e inclui o primeiro Datatable no DataSet
            Dim ds As DataSet = New DataSet("mergeComDataSet")
            ds.Tables.Add(dtbl_Clientes1)

            'mescla os dois DataTable via DataSet
            ds.Merge(dtbl_Clientes2)

            'exibe os dados mesclados no datagrid - dgMergeDataTable 
            dgMergeDataTable.DataSource = dtbl_Clientes1

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
   End Sub

 

2- Como é no ADO.NET 2.0 usando o VB 2005 Express

 

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        'monta a instrução SQL e define a string de conexão com o MSDE(instalado na minha maquina)
        Dim strSQL As String = "SELECT * FROM Customers"
        Dim cnStr As String = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;User ID=sa;_ 
                                       password=;Data Source=MACORATI\VSDOTNET"
        Dim cn As SqlConnection = New SqlConnection(cnStr)

        Try
            'abre a conexão com o MSDE/Northwind
            cn.Open()
            'define o comando SQL o DataAdapter e cria o DataTable
            Dim cmd As SqlCommand = New SqlCommand(strSQL, cn)
            Dim da As SqlDataAdapter = New SqlDataAdapter(cmd)
            Dim dtbl_Clientes1 As DataTable = New DataTable("Customers")

            'preenche o DataTable
            da.Fill(dtbl_Clientes1)
            'defina a coluna como chave primaria 
            dtbl_Clientes1.PrimaryKey = New DataColumn() {dtbl_Clientes1.Columns("CustomerID")}
            'faz uma copia da estrutura do primeiro DataTable
            Dim dtbl_Clientes2 As DataTable = dtbl_Clientes1.Clone
            'cria a primeira linha no segundo DataTable
            Dim linha1 As DataRow = dtbl_Clientes2.NewRow
            linha1("CustomerID") = "ALFKI"
            linha1("CompanyName") = "JcmSoft Inc."
            dtbl_Clientes2.Rows.Add(linha1)
            'cria a segunda linha no segundo DataTable
            Dim linha2 As DataRow = dtbl_Clientes2.NewRow
            linha2("CustomerID") = "JCM"
               linha2("CompanyName") = "Macoratti.net"
            dtbl_Clientes2.Rows.Add(linha2)

             ' efetua o Merge dos DataTables e exibe os dados no DataGridView
               dtbl_Clientes1.Merge(dtbl_Clientes2)
              dgvMergeSemDataSet.DataSource = dtbl_Clientes1
         
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

 

CreateDataReader - método que retorna um novo objeto chamado DataTableReader e que pode ser utilizado para ler dados do DataTable.

 


O DataTableReader apresenta o conteúdo de um DataTable ou DataSet na forma de um ou mais conjunto de dados do tipo somente-leitura e navegação somente-para-frente.

Quando você criar um DataTableReader a partir de um DataTable, o objeto DataTableReader resultante contém um result set com os mesmos dados que o DataTable a partir do qual foi criado; somente as linhas marcadas como deletadas não estão contidas no DataTableReader.  As colunas permanecem na mesma ordem que possuíam no DataTable.

O DataTableReader pode conter múltiplos conjuntos de dados se for criado pela chamada do método CreateDataReader.

 

Um DataTableReader se comporta e trabalha como os leitores de dados como o SQLDataReader, a diferença é que ele fornece meios de iteração sobre as linhas do DataTable. Enquanto o DataTableReader estiver ativo as linhas podem sofre alteração.

 

Afim de garantir que a ordem dos conjuntos de dados retornados com o DataTableReader, se um DataTable em um DataSet estiver vazio, ele é representado por um conjunto de dados vazio no DataTableReader retornado.

 

O objeto DataTableReader é mais leve que o DataTable e não é conectado como um DataReader; ele é desconectado. Assim você tem um objeto que consome poucos recursos e esta desconectado podendo fazer iterações diretamente nas linhas das tabelas. Lembrando que um DataTableReader somente pode ser percorrido para frente. Para mover-se para a primeira linha usamos o método Read().

 

A seguir temos um exemplo, tirado da MSDN, onde são criados 3 instâncias do DataTable e a seguir são incluídas em um DataSet. O método CreateDataReader cria um DataTableReader com conteúdo dos objetos DataTable: tabelaProdutos, tabelaVazia e tabelaClientes.

 

    Private tabelaVazia As DataTable
    Private tabelaClientes As DataTable
    Private tabelaProdutos As DataTable

    Private Sub TesteCreateDataReader(ByVal dataSet As DataSet)
        ' Recebe um DataSet, retorna um DataTableReader
        ' permitindo acesso a todos os dados do DataSet.

        Using reader As DataTableReader = dataSet.CreateDataReader(tabelaProdutos, tabelaVazia, tabelaClientes)


            'percorre todos os conjunto de dados do DatatableReader
            Do
                If Not reader.HasRows Then
                    MsgBox("DataTableReader vazio")
                Else
                    exibirColunas(reader)
                End If
            Loop While reader.NextResult()
        End Using
    End Sub
 
    Private Function obtemClientes() As DataTable
        ' Cria um tablea exemplo de clientes
        ' para demonstrar o comportamenteo do  DataTableReader.
        Dim Tabela As New DataTable

        ' Cria duas colunas: ID e Name.
        Dim idColumn As DataColumn = Tabela.Columns.Add("ID", GetType(Integer))
        Tabela.Columns.Add("Name", GetType(String))
        ' Define a coluna ID como a coluna da chave primária
        Tabela.PrimaryKey = New DataColumn() {idColumn}
        Tabela.Rows.Add(New Object() {1, "Macoratti"})
        Tabela.Rows.Add(New Object() {2, "Miriam"})
        Tabela.Rows.Add(New Object() {3, "Jessica"})
        Tabela.Rows.Add(New Object() {4, "Jefferson"})
        Return Tabela
    End Function

    Private Function obtemProdutos() As DataTable
        ' Cria uma tabela exemplo chamada Produtos
        Dim Tabela As New DataTable
        ' Cria duas colunas: ID e Name.
        Dim idColumn As DataColumn = Tabela.Columns.Add("ID", GetType(Integer))
        Tabela.Columns.Add("Name", GetType(String))
        ' Define a coluna ID como a coluna da chave primária
        Tabela.PrimaryKey = New DataColumn() {idColumn}
        Tabela.Rows.Add(New Object() {10, "Super CD Visual Basic"})
        Tabela.Rows.Add(New Object() {20, "Super CD .NET"})
        Tabela.Rows.Add(New Object() {30, "Super CD ASP total"})
        Tabela.Rows.Add(New Object() {40, "Sistema Finanças"})
        Return Tabela
    End Function

    Private Sub exibirColunas(ByVal reader As DataTableReader)

        ' Percorre todas as linhas dos conjuntos de dados do DataTableReader e exibe no Listbox
        Do While reader.Read()
            For i As Integer = 0 To reader.FieldCount - 1
                ListBox1.Items.Add(reader(i).ToString())
            Next
        Loop
    End Sub
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         'cria um dataset
        Dim dataSet As New DataSet
 
        ' Inclui algumas tabelas no DataSet, incluindo um DataTable vazio
        tabelaVazia = New DataTable()
        tabelaProdutos = obtemProdutos()
        tabelaClientes = obtemClientes()

        dataSet.Tables.Add(tabelaClientes)
        dataSet.Tables.Add(tabelaVazia)
        dataSet.Tables.Add(tabelaProdutos)
        TesteCreateDataReader(dataSet)
    End Sub

 

Aguarde em breve mais artigos sobre os novos recursos da .NET Framework 2.0.

 

Eu sei, é apenas VB, mas eu gosto  !!!


José Carlos Macoratti