.NET

1 set, 2011

Como realizar as operações CRUD em uma aplicação WPF com DataGrid usando o Linq to SQL

Publicidade

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:

  1. 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

  2. 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.

Pegue o projeto completo
aqui:  Wpf_DataGrid_Crud.zip