ASP.NET - GridView Manutenção completa de dados


Já escrevi diversos artigos sobre o GridView (veja referências) e neste artigo vou mostrar como usar o GridView em um projeto ASP .NET para realizar a manutenção completa das informações de um banco de dados permitindo a inclusão, alteração e atualização dos dados.

Você vai precisar dos seguintes recursos para acompanhar este artigo:

O exemplo usado neste artigo será aplicado a tabela Categories do banco de dados Norhtwind.mdf

A primeira coisa que vamos fazer será criar 3 procedimentos armazenados , stored procedures , nomeados como:

  1. sp_UpdateCategories
  2. sp_SelectCategories
  3. sp_DeleteCategories

Vamos criar as stored procedures no próprio Visual Web Developer 2005 Express. Abra o WVD e crie um novo web site chamado : gridManutencao;

Ative o DataBase Explorer no menu View e crie uma conexão com o banco de dados Northwind.mdf se ela não existir. Você deverá visualizar na janela DataBase Explorer a conexão conforme figura abaixo:

Clique com o botão direito do mouse sobre Stored Procedures e selecione Add New Stored Procedure informando o texto conforme a figura abaixo:

Esta stored procedure servirá para atualizar e para incluir dados na tabela Categories.

A variável @@ROWCOUNT é usada para obter as linhas afetadas. Se o seu valor for igual a zero temos que a categoria com o dadosCategorias informado não existe, e, então deveremos incluir os dados na tabela usando a instrução INSERT INTO.

Obs: Como a coluna chave primária CategoryID foi definida com o atributo identity, significa que o SQL Server se encarregará de informar este valor automaticamente no momento em que a linha for criada na tabela. Dessa forma ele não é usado no comando INSERT INTO.

A função @@IDENTITY contém o último valor identity gerado em qualquer tabela na sessão atual. Pode ser afetado por Triggers e pode não conter o valor identity que você espera.

Para retornar o valor de um campo identity de uma nova linha incluída no SQL Server usamos uma stored procedure com um parâmetro de saída (OUTPUT Parameter).

Repita o processo acima para criar as outras duas stored procedures. Veja o código de cada uma delas:

CREATE PROCEDURE dbo.sp_SelectCategories
As
Select CategoryID,
          CategoryName,
           Description
From Categories
  CREATE PROCEDURE dbo.sp_DeleteCategories
@CatID as integer
As
Delete from Categories
Where CategoryID=@CatID

Ao terminar esta etapa você deverá visualizar as 3 stored procedures conforme figura abaixo:

Vamos criar a interface da aplicação na página Default.aspx seguindo o leiaute da figura abaixo:

No menu Layout selecione a opção Insert Table e defina uma tabela com uma linha e 3 colunas:

A seguir inclua 3 componentes LinkButton com a propriedade Text = Incluir, Processa e Atualizar e ID igual a linkAddRow, linkRefresh e linkUpdate em cada uma das colunas da tabela.

Devemos definir ainda no evento OnClick de cada controle LinkButton uma rotina que deverá ser executada quando o usuário clicar no link:

Veja o código completo abaixo:

<table style="width: 62%"><tr>
        <td style="width: 180px; height: 21px;">
           <asp:LinkButton ID="lnkAddRow" Font-Bold="True" runat="server" 
           OnClick="lnkAddRow_Click">Incluir</asp:LinkButton></td>
        <td align="center" style="width: 283px; height: 21px;">
            <asp:LinkButton ID="lnkRefresh" runat="server" Font-Bold="True" 
            OnClick="lnkRefresh_Click">Processa</asp:LinkButton></td>
        <td align="right" style="width: 33px; height: 21px;">
            <asp:LinkButton ID="lnkUpdate" Font-Bold="True" runat="server" 
            OnClick="lnkUpdate_Click" Width="255px">Atualizar</asp:LinkButton></td>
    </tr>
</table>

Agora inclua um componente GridView a partir da ToolBox abaixo da tabela recém-criada chamado gvCategories.

Selecione o GridView e em GridView Tasks clique no link Edit Fields e crie 3 Template Fields conforme a figura abaixo:

Vamos definir os templates Fields : Delete, Category e Description :

1- Delete

ItemTemplate:
- Controle ImageButton - propriedade ImageURL = ~/Images/Cancel.jpg

No evento OnClientClick do controle vamos definir uma rotina JavaScript solicitando a confirmação da exclusão:

OnClientClick="return confirma('Confirma a exclusão desta Categoria?');"

- Label - DataBindings - Text - Bind("CategoryID")

2- Category

- ItemTemplate - TextBox - DataBindings - Text = Bind("CategoryName")

3 - Description

ItemTemplate : TextBox - DataBindings - Text = Bind("Description")

Inclua abaixo do GridView um controle Label chamado lblResultados.

Perceba que eu não estou usando o SQLDataSource pois vou fazer todo o serviço via código.

Defina o namespace System.Data.SqlClient responsável pela conexão com o SQL Server;

Imports System.Data.SqlClient

Vamos declarar uma variável a ser usada para a conexão do tipo SqlConnection;

Dim conexaoBD As SqlConnection

Agora no evento Load vamos obter a a conexão a partir do arquivo web.config e chamar a rotina vinculaGrid() ;

 Sub Page_Load(ByVal Source As Object, ByVal E As EventArgs)

       conexaoBD = New SqlConnection(ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString)

        If Not Page.IsPostBack Then
             vinculaGrid()
        End If
 End Sub

Definimos a propriedade dadosCategoria que define e retorna um DataTable no e a partir do ViewState;

A propriedade ViewState do ASP.NET para páginas e controles individuais tem duas finalidades:  manter o estado entre solicitações e armazenar valores personalizados em um campo oculto protegido e resistente a violações.
Ref.
: ASP.NET State Management: View State e Usando Web Forms II
Property dadosCategoria() As System.Data.DataTable
        Get
            Dim o As Object = ViewState("dadosCategoria")
            If o Is Nothing Then
                Return Nothing
            Else
                Return o
            End If
        End Get
        Set(ByVal value As System.Data.DataTable)
            ViewState("dadosCategoria") = value
        End Set
End Property

Esta propriedade retorna um objeto do tipo DataTable que será usado para preencher o GridView através da rotina vinculaGrid();

Sub vinculaGrid()
        dadosCategoria = obtemCategorias()
        gvCategories.DataSource = dadosCategoria
        gvCategories.DataBind()
        lblResults.Text = ""
    End Sub

A rotina vinculaGrid preenche o GridView obtendo os dados através da rotina GetCategories();

Function obtemCategorias() As DataTable
  
        Dim dt As New DataTable
        Dim da As SqlDataAdapter
        Dim cmd As New SqlCommand("sp_SelectCategories", conexaoBD)

        cmd.CommandType = CommandType.StoredProcedure
        da = New SqlDataAdapter(cmd)
        da.Fill(dt)

        obtemCategorias = dt

        conexaoBD.Close()
End Function

A função obtemCategorias() retorna um DataTable e usa a stored procedure sp_SelectCategories;

Sub DeleteCategory(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs)
       
        Dim lbl As Label = CType(sender.findcontrol("lblID"), Label)

        If lbl.Text = "-1" Then
            dadosCategoria.Rows.RemoveAt(0)
        Else
            DeleteCategory_ByCatID(lbl.Text)
        End If

        vinculaGrid()

        lblResultados.Text = "Exclusão realizada com sucesso."

    End Sub

A rotina DeleteCategory efetua a exclusão de um registro chamando a rotina DeleteCategory_ByCatID que usa a stored procedure : sp_UpdateCategories

Sub DeleteCategory_ByCatID(ByVal CatID As Integer)
   
      Dim cm As New SqlCommand("sp_DeleteCategories", conexaoBD)

        cm.Parameters.Add("@CatID", SqlDbType.Int).Value = CatID
        cm.CommandType = CommandType.StoredProcedure

        conexaoBD.Open()

        cm.ExecuteNonQuery()
        conexaoBD.Close()
        cm = Nothing
    End Sub

Para atualizar os dados usamos a rotina UpdateCategory passando os parâmetros: CatName, Desc e catID que serão usados na stored procedure: sp_UpdateCategories;

Function UpdateCategory(ByVal CatName As String, ByVal Desc As String, ByVal catID As Integer) As Integer
      Dim iRet As Integer
        Dim cm As New SqlCommand("sp_UpdateCategories", conexaoBD)

        cm.Parameters.Add("@CategoryName", SqlDbType.NVarChar).Value = CatName
        cm.Parameters.Add("@Description", SqlDbType.NText).Value = Desc

        If catID > 0 Then
            cm.Parameters.Add("@CatID", SqlDbType.Int).Value = catID
        End If

        Dim IDOut As New SqlParameter("@IDOut", SqlDbType.Int)
        IDOut.Direction = ParameterDirection.ReturnValue
        cm.Parameters.Add(IDOut)

        cm.CommandType = CommandType.StoredProcedure

        If conexaoBD.State = ConnectionState.Closed Then
            conexaoBD.Open()
        End If
        If catID > 0 Then
            cm.ExecuteNonQuery()
        Else
            cm.ExecuteScalar()
            iRet = CInt(IDOut.Value)
            Return iRet
        End If

        conexaoBD.Close()
End Function

O evento Click do link Incluir inclui uma nova linha no GriView e permite a inclusão dos dados;

Sub lnkAddRow_Click(ByVal sender As Object, ByVal e As System.EventArgs)
       dadosCategoria = obtemCategorias()

        Dim dr As DataRow = dadosCategoria.NewRow()

        dr("CategoryID") = -1

        dadosCategoria.Rows.InsertAt(dr, 0)

        gdvCategorias.DataSource = dadosCategoria
        gdvCategorias.DataBind()  
End Sub

O evento Click do link Atualizar efetua a atualização dos dados chamando a rotina UpdateCategory com os parâmetros necessários obtidos a partir dos controles do GriView;

 Protected Sub lnkUpdate_Click(ByVal sender As Object, ByVal e As System.EventArgs)
   Dim linhaAtual As Integer
        Dim iCatID As Integer

        If gdvCategorias.Rows.Count > 0 Then

            For linhaAtual = 0 To gdvCategorias.Rows.Count - 1
                With gdvCategorias.Rows(linhaAtual)

                    Dim sCat As String
                    Dim sDesc As String
                    Dim CatID As Integer

                    sCat = CType(.FindControl("txtCategoryName"), TextBox).Text
                    sDesc = CType(.FindControl("txtDescription"), TextBox).Text

                    If IsNumeric(CInt(CType(.FindControl("lblID"), Label).Text)) Then
                        If CInt(CType(.FindControl("lblID"), Label).Text) > 0 Then
                            CatID = CInt(CType(.FindControl("lblID"), Label).Text)
                        End If
                    End If

                    iCatID = UpdateCategory(sCat, sDesc, CatID)
                End With
            Next

            lblResultados.Text = "Atualização realizada com sucesso."
        End If       
 End Sub

Finalmente o evento Click do link Processa apenas atualiza a exibição dos dados no GridView;

 Protected Sub lnkRefresh_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        vinculaGrid()
    End Sub

A seguir temos uma sequência de telas exibindo a aplicação em 3 estados básicos:

1- Na carga inicial a aplicação apresenta os dados no GridView

2- Ao clicar no link Incluir temos uma nova linha inserida no inicio do GridView onde o usuário informa os novos dados;

3- Após incluir os dados e clicar no link Atualizar , o usuário pode clicar no link Processa para atualizar a exibição dos dados e também no informa novos valores e clicar no link Atualizar para realizar alterações;

E pronto , criarmos uma pequena aplicação usando o GridView , algumas stored procedures e um pouco de código que realiza a manutenção dos dados de uma tabela. Tudo isso sem usar os assistentes para criação de fonte de dados(SqlDataSource).

Pegue o projeto completo aqui:   gridManutencao.zip

Eu sei é apenas ASP.NET , mas eu gosto...

Referências:


José Carlos Macoratti