Neste artigo eu vou mostrar como realizar as operações CRUD em uma aplicação WPF com DataGrid usando o Linq to SQL.
Abra o Visual Basic 2010 Express Edition e crie uma nova aplicação WPF com o nome: Wpf_DataGrid_Crud.
Definindo a fonte de dados
Como fonte de dados, eu estou usando um banco de dados SQL Server criado no SQL Server Management Studio com o nome Cadastro.mdf e a tabela Alunos que possui os campos: Id, Nome , Idade e Email.
Abaixo podemos ver na figura o banco de dados, a tabela e seus campos e alguns dados que eu já incluí na tabela.
Para acessar e realizar as operações CRUD, eu poderia usar um DataSet, o NHibernate, o Entity Framework, mas neste artigo eu vou usar o Linq to SQL para mostrar que, embora ofuscado pelo Entity Framework, ele ainda pode ser usado para operações simples como a deste artigo.
Quando pensamos em acesso a dados na plataforma .NET, pensamos em ADO .NET, certo?
Pois bem, como fazemos atualmente para acessar os dados em um banco relacional com ADO .NET? Geralmente efetuamos a representação das tabelas do banco de dados em classes de forma a criar uma interface para persistência das informações.
Isso é feito hoje basicamente de duas formas:
- Fazer o mapeamento objeto-relacional usando DataSets e o acesso a dados através de DataAdapters ou TableAdapters com ajuda dos Assistentes de configuração
- Fazer o mapeamento objeto-relacional através da criação das classes de negócio via código e acessando os dados usando DataReader
O LINQ To SQL tem o objetivo de reunir o melhor das duas opções, de forma que você possa fazer o mapeamento objeto-relacional criando classes que representam as tabelas do banco de dados, inclusive mapeando stored procedures como métodos e, com isso, possibilitando a criação de consultas e as alterações no banco de dados usando a sintaxe LINQ. Na verdade, as consultas criadas na ‘linguagem’ LINQ são convertidas em código T-SQL, sendo retornada uma coleção de objetos.
Agora vamos incluir a partir do menu Project->Add New Item e a partir da janela Templates o item LINQ to SQL Classes, alterando o nome para Cadastro.dbml e clicando no botão Add.
Neste momento, será exibida a janela do descritor Objeto Relacional. Expanda os objetos do banco de dados Cadastro.mdf e selecione a tabela ‘Alunos’. Arraste-a e solte-a na janela do descrito ORM.
A tabela do banco de dados será mapeada como uma classe (campos como propriedades, procedures e funções como métodos) e você terá no Descritor a classe ‘Aluno’, que representa a tabela ‘Alunos’ do banco de dados.
O arquivo Cadastro.dbml contém o arquivo XML com informações sobre o leiaute da tabela que foi mapeada e também o descritor contendo a classe gerada pelo mapeamento. Após encerrar o mapeamento, você já terá acesso aos recursos do LINQ To SQL com direito a intellisense completo das informações referentes à tabela, mesmo sem conhecer nada sobre ela. Se você abrir a janela de propriedades, verá que o arquivo cadastro.dbml será identificado pelo nome CadastroDataContext e representando o nosso contexto de acesso às classes.
Nota: Você deve definir a chave primária na tabela ‘Aluno’ para que as operações sejam processadas sem erros.
Definindo a interface
Vamos agora criar no arquivo MainWindow.xaml a interface da nossa aplicação que irá exibir os dados da tabela ‘Alunos’. Para isso, vou usar um controle DataGrid definido conforme o leiaute da figura abaixo:
O código XAML usado para definir o leiaute acima pode ser visto abaixo:
<Window x:Class=”MainWindow”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Title=”WPF – DataGrid – CRUD com LINQ To SQL” Height=”350″ Width=”525″>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=”0.912*”/>
<RowDefinition Height=”0.088*”/>
</Grid.RowDefinitions>
<DataGrid x:Name=”dgData” Margin=”0″ AutoGenerateColumns=”False”
RowEditEnding=”dgData_RowEditEnding”
CommandManager.PreviewExecuted=”dgData_PreviewExecuted”
CanUserAddRows=”True” CanUserDeleteRows=”True”>
<DataGrid.Columns>
<DataGridTextColumn Binding=”{Binding Id}” Header=”ID” IsReadOnly=”True”/>
<DataGridTextColumn Binding=”{Binding Nome}” Header=”Nome” Width=”150″/>
<DataGridTextColumn Binding=”{Binding Idade}” Header=”Idade”/>
<DataGridTextColumn Binding=”{Binding Email}” Header=”Email” Width=”*”/>
</DataGrid.Columns>
</DataGrid>
<TextBlock x:Name=”txtStatus” HorizontalAlignment=”Left” Margin=”8,0,0,0″ Grid.Row=”1″
TextWrapping=”Wrap” VerticalAlignment=”Center”/>
</Grid>
</Window>
Agora abra o arquivo MainWindow.xaml.vb e inclua o seguinte código no evento Loaded da janela Window:
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim ctx As New CadastroDataContext
Dim result = From emp In ctx.Alunos
If result.ToList().Count > 0 Then
txtStatus.Text = “Operação de leitura do arquivo.”
End If
dgData.ItemsSource = result.ToList()
End Sub
Se você executar o código agora (não se esqueça de definir os eventos: dgData_PreviewExecuted e dgData_RowEditEnding), deverá obter o seguinte resultado:
Agora, no evento dgData_RowEditEnding, vamos incluir o código para realizar a inclusão e a atualização dos dados conforme abaixo:
Private Sub dgData_RowEditEnding(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEditEndingEventArgs)
If e.EditAction = DataGridEditAction.Commit Then
Dim contexto As New CadastroDataContext()
Dim _aluno As Aluno = TryCast(e.Row.DataContext, Aluno)
Dim dadosEncontrados = (From em In contexto.GetTable(Of Aluno)() Where em.Id = _aluno.Id).SingleOrDefault()
If dadosEncontrados Is Nothing Then
Dim tabela = contexto.GetTable(Of Aluno)()
Dim _aluno1 As New Aluno()
_aluno1.Nome = _aluno.Nome
_aluno1.Idade = _aluno.Idade
_aluno1.Email = _aluno.Email
tabela.InsertOnSubmit(_aluno1)
tabela.Context.SubmitChanges()
txtStatus.Text = “Dados Inseridos.”
Else
dadosEncontrados.Nome = _aluno.Nome
dadosEncontrados.Idade = _aluno.Idade
dadosEncontrados.Email = _aluno.Email
contexto.SubmitChanges()
txtStatus.Text = “Dados atualizados”
End If
End If
End Sub
Para excluir um registro, vamos usar o evento dgData_PreviewExecuted, incluindo nele o código abaixo:
Private Sub dgData_PreviewExecuted(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
Dim _aluno As Aluno = TryCast(dgData.SelectedItem, Aluno)
If _aluno IsNot Nothing Then
Dim alunoEncontrado = (From em In contexto.GetTable(Of Aluno)() Where em.Id = _aluno.Id).SingleOrDefault()
If e.Command.Equals(DataGrid.DeleteCommand) Then
If Not (MessageBox.Show(“Deseja excluir este registro ?”, “Confirma Exclusão !”, MessageBoxButton.YesNo) = MessageBoxResult.Yes) Then
e.Handled = True
Else
contexto.Alunos.DeleteOnSubmit(alunoEncontrado)
contexto.SubmitChanges()
txtStatus.Text = “O registro foi excluído.”
End If
End If
End If
End Sub
Executando o projeto, iremos obter:
Atualizando dados:
Incluindo um aluno novo:
Excluindo um aluno
Assim, pudemos conferir a utilização do LINQ to SQL em uma aplicação WPF para realizar as operações CRUD em um banco de dados SQL Server. O Entity Framework seria uma escolha mais adequada pelos recursos disponíveis e por poder ser usado com qualquer banco de dados.
Fonte: José Carlos Macoratti / IMasters