VB.NET
- Criando uma aplicação em 3 camadas (MVC)
No artigo - Padrões de Projeto : O modelo MVC - Model View Controller - falei sobre os padrões de projeto , mais especificamente do modelo MVC. Vou mostrar neste artigo um exemplo prático de como podemos criar uma aplicação em 3 camadas , bem próxima do modelo MVC , usando o VB.NET.
Vou criar um projeto do tipo VB.NET com um formulário e um datagrid usando o acesso a dados via DataSet para criar uma aplicação em 3 camadas que permita acessar , alterar e atualizar os dados usando o DataGrid e refletir isto em um DataSet que representa a tabela Customer do banco de dados Northwind.mdb.
O código irá mostrar como enviar novas linhas (registros) , alterar linhas e excluir linhas usando uma camada de serviços que atualiza o banco de dados usando um DataSet. Iremos dividir logicamente nosso projeto em 3 partes :
A aplicação que irei desenvolver pode ser dividido em dois projetos distintos : Um projeto baseado em Windows-Forms para apresentar os dados para o usuário e um projeto do tipo Class Library para gerenciar as regras de negócios e fazer a chamada para manipular os dados. (Os serviços de negócios ficariam responsáveis pelas tarefas de retornar e atualizar os dados na fonte de dados.)
A camada de apresentação - Windows Forms
Vamos começar com a camada de apresentação. Abaixo temos o formulário do projeto com os seguintes componentes:
![]() |
- 1 DataGrid - grdData - 3 Buttons - Button1 , Button2 e Button3 O componente DataGrid irá exibir os dados ao usuário e os botões irão ter as seguintes funcionalidades :
Por que estou usando um DataGrid ? Bem... O DataGrid é um controle de Servidor que pode ser facilmente manipulado para renderizar um conjunto de registros pela vinculação com um DataSet. |
Você deve estar meio desconfiado e deve também estar duvidando que é possível criar uma aplicação 3 camadas da forma com eu estou fazendo. Com certeza ao ler que eu vou vincular o DataSet ao DataGrid você pode até pensar que a vinculação será feita feita como nos velhos tempos do VB6.
Calma !!! No mundo .NET vincular tem um sentido muito diferente. Quando um DataSet é vinculado a um DataGrid , os dados do DataSet são copiados para o DataGrid. As alterações feitas nos dados do DataGrid são então repassadas para o DataSet para refletir as mundaças. Qual a diferença ??? Vou explicar ...
Quando você usava o VB6 e a ADO (lembra ???) as técnicas de vinculação de dados envolviam vincular os dados do Grid diretamente a um controle Data e dai para o banco de dados. Neste esquema a conexão com o banco de dados fica aberta o que limita muito nossa aplicação pois você tem a camada de apresentação diretamente ligada com a camada de dados.
Com o VB .NET temos o grid ainda vinculado ao DataSet , mas o DataSet não tem uma conexão com o banco de dados. Na verdade o DataSet nem mesmo sabe ou se importa em saber de onde os dados estão vindo. O DataSet pode ser preenchido com dados a partir de uma variedade de fonte de dados e até mesmo se preenchido manualmente sem fonte de dados alguma. Ai que esta a diferença...
Quando o usuário altera os dados no DataGrid do formulário, as mudanças são enviadas ao DataSet de forma automática. Qualquer nova linha de registro incluída é também incluída no DataSet e qualquer linha alterada é atualizada no DataSet. Linhas excluídas do DataGrid são removidas do DataSet (elas são marcadas como excluidas).
O DataSet trata todas as mudanças nos dados armazenando o valor original e atual de cada linha e coluna. Assim , se um DataGrid contiver 1000 linhas de dados e o usuário alterar 3 linhas, incluir 1 nova linha e excluir outras 2 linhas, as linhas afetadas podem ser extraíadas do DataSet vinculado para outro DataSet de maneira que o novo DataSet irá conter somente estas 6 linhas alteradas.
A seguir o código da classe frmMain : Aqui temos a classe frmMain onde a variável m_oDS representa o DataSet.
|
Public Class frmMain Inherits System.Windows.Forms.Form '//---------------------------------------------------------------------------------------------------- '// Declara variável de class '//---------------------------------------------------------------------------------------------------- Private m_oDS As DataSet
'//---------------------------------------------------------------------------------------------------- '// Retorna e carrega os dados para o formulário '//---------------------------------------------------------------------------------------------------- Private Sub LoadData() Dim oCustomer As BusinessServices.Customer = New BusinessServices.Customer()grdData.DataBindings.Clear() m_oDS = oCustomer.GetData() grdData.DataSource = m_oDS.Tables("Customer") oCustomer = Nothing End Sub '//------------------------------------------------------------------------------------------------------------ '// Envia os dados alterados para os serviços de negócios '//------------------------------------------------------------------------------------------------------------ Private Sub SaveData()
Dim lRetVal As Long Dim oCustomer As BusinessServices.Customer = New BusinessServices.Customer() Dim oDS_Delta As DataSet Dim sMsg As String'//--- Verifica se houve alterações If m_oDS Is Nothing Then Exit SubIf Not m_oDS.HasChanges() Then Exit Sub '//--- Trata todas as mudanças oDS_Alterados = m_oDS.GetChanges() sMsg = "Esta certo que quer salvar " & oDS_Alterados.Tables(0).Rows.Count() & " linhas da fonte de dados ? " lRetVal = MsgBox(sMsg, Microsoft.VisualBasic.MsgBoxStyle.Question + Microsoft.VisualBasic.MsgBoxStyle.YesNo, "Salva Dados") Select Case lRetVal Case vbYes Try '//--- Salva todas as alterações sMsg = oCustomer.SaveData(oDS_Alterados) LoadData() Catch e As Exception sMsg = "Erro ao salvar dados." & vbCrLf & vbCrLf & e.Message.ToString() Finally MsgBox(sMsg, Microsoft.VisualBasic.MsgBoxStyle.Information, "Salva Dados") End Try Case vbNo '//--- Nada End Select oDS_Delta = NothingoCustomer = Nothing End SubPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click LoadData() End SubPrivate Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click SaveData() End SubPrivate Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Me.Dispose() End Sub
End Class |
- Quando o usuário clicar no botão - Carregar Dados - o método LoadData() será invocado . Nele estamos declarando e criando uma instância da classe serviços de negócios :
Dim oCustomer As BusinessServices.Customer = New BusinessServices.Customer()
- A seguir declaramos a vinculação de dados e iniciamos com o status clear (limpo). Então usamos o método GetData do objeto de serviços de negócios - oCustomer - para retornar o DataSet preenchido com os dados da tabela - Customer - para o formulário através do DataGrid. Feito isto o DataSet será local e estará vinculado ao DataGrid.
grdData.DataBindings.Clear()
m_oDS = oCustomer.GetData()
grdData.DataSource = m_oDS.Tables("Customer")
oCustomer =
Nothing- Com os dados preenchendo o DataGrid e sendo exibidos no formulário o usuário poderá interagir com os dados via interface : alterando , excluindo e incluindo novos registros. Para salvar as alterações o usuário irá clicar no botão - Salvar Dados - que irá invocar o método SaveData().
- O método SaveData() cria uma instância dos objetos de serviços - BusinessServices.Customer() - e verifica se houve qualquer alteração nos dados usando o método HasChanges(). Como o DataSet esta vinculado ao DataGrid qualquer alteração feita será refletida no DataSet. Havendo alterações eu utilizo a variável oDS_Alterados para armazenar os registros alterados : oDS_Alterados = m_oDS.GetChanges()
- O método GetChanges do DataSet copia as linhas alteradas do DataSet e as coloca em um novo DataSet: oDS_Alterados.
- Finalmente o usuário deverá confirmar se deseja salvar as alterações
A camada de serviços
A camada de serviços é definida em uma classe chamada : BusinessServices. O código da classe esta descrito a seguir :
|
'//-------------------------------------------------------------------------------------------------------- '// Declara todos os NameSpaces que serão referenciados '//-------------------------------------------------------------------------------------------------------- Imports SystemImports System.DataImports System.Data.OleDb'//-------------------------------------------------------------------------------------------------------------- '// NameSpace BusinessServices '//-------------------------------------------------------------------------------------------------------------- Namespace BusinessServicesPublic Class Customer '//---------------------------------------------------------------------------------------------------- '// Declara as variáveis de Classe '//---------------------------------------------------------------------------------------------------- Private m_sProvider As String = "PROVIDER=Microsoft.Jet.OLEDB.4.0;" Private m_sServer As String = "DATA SOURCE=C:/teste/" ' Private m_sDatabase As String = "Northwind1.mdb" Private m_oDS As DataSet Private m_oCn As OleDbConnection Private m_oDA As OleDbDataAdapter Private m_sClassName As String = "Customer" '//--- o nome da classe '//---------------------------------------------------------------------------------------------------- '// Constructor (sem argumentos) '//---------------------------------------------------------------------------------------------------- Sub New() Dim sSQL As String = "" Dim oSelCmd As OleDbCommand Dim oInsCmd As OleDbCommand Dim oUpdCmd As OleDbCommand Dim oDelCmd As OleDbCommand '--------------------------------------------------------- '--- define a conexao '---------------------------------------------------------InitializeConnection() '--------------------------------------------------------- '--- define o SELECT Command '---------------------------------------------------------sSQL = "SELECT CustomerID, CompanyName, ContactName, City, Region FROM Customers ORDER BY CompanyName "
oSelCmd = NothingoSelCmd = New OleDbCommand(sSQL, m_oCn)oSelCmd.CommandType = CommandType.Text '--------------------------------------------------------- '--- define o UPDATE Command '---------------------------------------------------------sSQL = "UPDATE Customers " & _ " SET CompanyName = @CompanyName , ContactName = @ContactName, City = @City, Region = @Region WHERE CustomerID = @CustomerID "
oUpdCmd = NothingoUpdCmd = New OleDbCommand(sSQL, m_oCn)
With oUpdCmd .CommandType = CommandType.Text With .Parameters .Add(New OleDbParameter("@CompanyName", OleDbType.VarChar, 40, "CompanyName")) .Add(New OleDbParameter("@ContactName", OleDbType.VarChar, 30, "ContactName")) .Add(New OleDbParameter("@City", OleDbType.VarChar, 15, "City")) .Add(New OleDbParameter("@Region", OleDbType.VarChar, 15, "Region")) .Add(New OleDbParameter("@CustomerID", OleDbType.LongVarChar, 5, "CustomerID")) End With End With '--------------------------------------------------------- '--- define o INSERT Command '---------------------------------------------------------sSQL = "INSERT INTO Customers " & _ " (CompanyName, ContactName, City, Region, CustomerID) VALUES (@CompanyName, @ContactName, @City, @Region, @CustomerID)" oInsCmd = NothingoInsCmd = New OleDbCommand(sSQL, m_oCn)
With oInsCmd .CommandType = CommandType.Text With .Parameters .Add(New OleDbParameter("@CompanyName", OleDbType.VarChar, 40, "CompanyName")) .Add(New OleDbParameter("@ContactName", OleDbType.VarChar, 30, "ContactName")) .Add(New OleDbParameter("@City", OleDbType.VarChar, 15, "City")) .Add(New OleDbParameter("@Region", OleDbType.VarChar, 15, "Region")) .Add(New OleDbParameter("@CustomerID", OleDbType.LongVarChar, 5, "CustomerID")) End With End With '--------------------------------------------------------- '--- define o DELETE Command '---------------------------------------------------------sSQL = "DELETE Customers WHERE CustomerID = @CustomerID " oDelCmd = NothingoDelCmd = New OleDbCommand(sSQL, m_oCn) With oDelCmd.CommandType = CommandType.Text With .Parameters .Add( New OleDbParameter("@CustomerID", OleDbType.LongVarChar, 5, "CustomerID"))End With End With '--------------------------------------------------------- '--- cria e define os comandos para o DataSet '--------------------------------------------------------- m_oDA = New OleDbDataAdapter() With m_oDA.SelectCommand = oSelCmd .UpdateCommand = oUpdCmd .DeleteCommand = oDelCmd .InsertCommand = oInsCmd End With '//--- Destroi o objeto connectionm_oCn = Nothing End Sub '//------------------------------------------------------------------------------------------------------------ Public Function SaveData(ByVal oDS As DataSet) As StringDim sMsg As String Dim lRecsAffected As Long Dim oTran As OleDb.OleDbTransaction '--------------------------------------------------------- '//--- Salva os dados '--------------------------------------------------------- Try '--- define a conexao InitializeConnection() m_oCn.Open() '--- inicia a transacao oTran = m_oCn.BeginTransaction() '--- atualiza o banco de dados lRecsAffected = m_oDA.Update(oDS, m_sClassName) '--- consolida (commit) as mudanças oTran.Commit() '--- define as mensagens para o usuario sMsg = lRecsAffected & " registros foram atualizados" Catch e As Exception '--- Ocorreu um erro Desfaz a transacao oTran.Rollback() sMsg = "Os registros não foram atualizados." & vbCrLf & e.Message.ToString() Finally '--- Fecha a conexao oTran = Nothingm_oCn.Close() m_oCn = NothingSaveData = sMsg End Try End Function '//------------------------------------------------------------------------------------------------------------// retorna os dados da tabela clientes '//------------------------------------------------------------------------------------------------------------ Public Function GetData() As DataSet'--- Cria um novo datase m_oDS = New DataSet()'--- preenche o dataset com os dados dos clientes m_oDA.Fill(m_oDS, m_sClassName) '//--- Retorna o dataset Return m_oDS End Function '//------------------------------------------------------------------------------------------------------------ '// Inicializa a conexão '//------------------------------------------------------------------------------------------------------------ Private Sub InitializeConnection() '--- define a conexaom_oCn = New OleDbConnection(m_sProvider & m_sServer & m_sDatabase) End SubEnd Class End Namespace
|
vai continuar ...
![]()
José Carlos Macoratti