WPF - DataGrid : CRUD com Linq To SQL


Neste tutorial 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 (veja referências) 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á inclui 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 com 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 têm 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 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 retornado uma coleção de objetos.)

Agora vamos incluir a partir do menu Project->Add New Item , 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 e 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 referente a 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 as 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 esqueça de definir os eventos : dgData_PreviewExecuted e dgData_RowEditEnding) deverá obter o seguinte resultado:

Agora no evento dgData_RowEditEnding vamos inclir o código para realizar a inclusão e 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 incluido 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 novo Aluno
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

Jesus dizia pois aos judeus que criam nele: Se vós permanecerdes na minha palavra, verdadeiramente sereis meus discípulos. E conhecereis a verdade e a verdade os libertará.(João 8:31-32)

Referências:


José Carlos Macoratti