VB .NET - Curso Prático ADO .NET - Módulo de Administração :  Definindo Consultas com LINQ - VII


Nesta aula vou mostrar como realizar algumas consultas em nosso módulo de administração da aplicação CiaFilmes usando o LINQ to Entities.

O recurso LINQ To Entities permite que o desenvolvedor escreva consultas contra um banco de dados a partir da mesma linguagem usada para construir a lógica de negócio.

Quem realiza a integração das funcionalidades do ADO .NET 2.0 (DataSet, DataAdapter,etc..) com o Entity Data Model e o LINQ é o ADO .NET Entity Framework.

A sintaxe LINQ

A LINQ é baseado em um conjunto de operadores de consulta, definidos como métodos de extensão, que trabalham com qualquer objeto que implemente a interface IEnumerable<T>.

A sintaxe básica da linguagem é:

var <variável> = from <elemento da lista> in <lista de dados>
                         where <clausula>
                         select <elemento>
Dim <variável> = from <elemento da lista> in <lista de dados>
                          where <clausula>
                          select <elemento>
C# VB .NET

Exemplo usando a sintaxe VB .NET :

Dim dados = From produtos In db.Products 
                  Where
 produtos.UnitPrice > 50 
                
  Order By produtos.ProductName 
                  
Select
 produtos.ProductName, produtos.UnitPrice

A consulta LINQ To SQL inicia com a cláusula From e em seguida o operador de condição Where depois ordenação com Order By, e, no final o operador de seleção Select.

Um dos motivos desta inversão de ordens é  o uso recurso IntelliSense, pois quando você indica primeiro a origem dos dados ele pode mostrar as listas de membros de tipos nos objetos em sua coleção.

Outro motivo , segundo Anders Hejlsberg , seria que a ordem esta mais próxima da nossa lógica de pensamento.

Quando você digita uma instrução SQL iniciando com Select na verdade você já esta pensando na origem dos dados , condições , agrupamentos. etc. (você concorda?)

A cláusula From é a mais importante do LINQ pois é usada em todas as consultas.

Uma consulta deve sempre começar com From. (O Select pode estar implícito o From não.)

A título de exemplo vou realizar 3 consultas básicas:

  1. Vendas diárias - Pedidos :  Que exibe os pedidos e seus detalhes para um determinado dia selecionado;
  2. Filmes - Pedidos : Que exibe os filmes mais pedidos;
  3. Clientes - Pedidos :  Que exibe os clientes que mais fizeram pedidos;

1- Consultando os pedidos e seus detalhes

Para saber os pedidos feitos em um dia e seus detalhes vamos incluir o formulário frmPedidosCliente.vb no projeto.

Abra o projeto CiaFilmesWinAdmin no Visual Studio 2012 Express for desktop;

No menu PROJECT -> Add Windows Forms informe o nome do formulário e a seguir inclua os seguintes controles:

Disponha os controles no formulário a partir da ToolBox conforme o leiaute abaixo:

No evento Load do formulário inclua o código que faz a chamada da rotina exibePedidos() passando a data de hoje como parâmetro da consulta:

Private Sub frmPedidosClientes_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        exibePedidos(Now.Date)
    End Sub

A rotina exibePedidos() recebe data e realiza uma consulta LINQ selecionando os pedidos dos clientes para aquela data:

 Private Sub exibePedidos(ByVal data As Date)
        Dim diaHoje As Date = data
        Dim valorTotalPedidos As Double = 0
        Try
            Using ctxFilmes = New CiaFilmesEntities()

                Dim pedidos = From ped In ctxFilmes.Pedidos.Include("Clientes")
                                      Where ped.PedidoData = diaHoje Select New With {ped.NumeroPedido,                                       ped.Clientes.Nome, ped.QuantidadeTotal, ped.ValorPedido}

                dgvPedidos.DataSource = pedidos.ToList
                For Each ped In pedidos
                    valorTotalPedidos += ped.ValorPedido
                Next

            End Using
            txtValorTotalPedidos.Text = String.Format("{0:C2}", valorTotalPedidos)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

Estou usando um laço For Each para percorrer os pedidos e calcular o valor total dos pedidos:

For Each ped In pedidos
                    valorTotalPedidos += ped.ValorPedido
Next

Para exibir os detalhes de um pedido basta clicar na respectiva linha referente ao pedido no DataGridView e usando o evento CellClick temos o código a seguir que obtém o número do pedido e efetua uma consulta LINQ para obter os seus detalhes:

Private Sub dgvPedidos_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvPedidos.CellClick
        If e.RowIndex <> -1 Then
            Dim numeroPedido As String = dgvPedidos(0, e.RowIndex).Value.ToString()
            Try
                Using ctxFilmes = New CiaFilmesEntities()

                    Dim detPedidos = From detPed In ctxFilmes.PedidosDetalhes.Include("Videos")
                                               Where detPed.NumeroPedido = numeroPedido
                                               Select New With {detPed.Videos.Filme.Titulo, detPed.Videos.Preco, detPed.Quantidade}

                    dgvItens.DataSource = detPedidos.ToList
                End Using
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End If
    End Sub

No evento ValueChanged do controle DateTimePicker estamos atualizando os dados a cada nova escolha de uma data chamando a rotina exibePedidos():

 Private Sub dtpDataPedido_ValueChanged(sender As Object, e As EventArgs) Handles dtpDataPedido.ValueChanged
        Dim data As String = dtpDataPedido.Value.ToString("dd/MM/yyyy")
        exibePedidos(Convert.ToDateTime(data))
        dgvItens.DataSource = Nothing
    End Sub

Abaixo vemos um exemplo de consulta realizada nesta opção:

2- Consultando os filmes mais pedidos

Para consultar os filmes mais pedidos vamos incluir um novo formulário em nosso projeto.

No menu PROJECT clique em  Add Windows Forms e informe o nome frmFilmesPedidos.vb;

A seguir inclua, a partir da ToolBox, os seguintes controles no formulário:

Disponha os controles no formulário a partir da ToolBox conforme o leiaute abaixo:

No evento Load do formulário inclua o código que chama a rotina exibeFilmes():

 Private Sub frmFilmesPedidos_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        exibeFilmes()
    End Sub

No código da rotina exibeFilmes() abaixo vemos a consulta LINQ que retorna os filmes mais pedidos:

 Private Sub exibeFilmes()
        Try
            Using ctxFilmes = New CiaFilmesEntities()
                Dim detPedidos = From detPed In ctxFilmes.PedidosDetalhes.Include("Videos")
                                         Group detPed By detPed.Videos.Filme.Titulo Into Count(detPed.VideoId)
                                         Order By Count Descending
                                         Select New With {Titulo, Count}
                gdvFilmes.DataSource = detPedidos.ToList
                formataGridView()
            End Using
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

Após a atribuição do resultado da consulta ao DataGridView invocamos a rotina formataGridView() que formata o controle. O código é visto abaixo:

 Private Sub formataGridView()
        With gdvFilmes
            .AutoGenerateColumns = False
            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
            .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single
            'altera a cor das linhas alternadas no grid
            .RowsDefaultCellStyle.BackColor = Color.White
            .AlternatingRowsDefaultCellStyle.BackColor = Color.Aquamarine
            'altera o nome das colunas
            .Columns(0).HeaderText = "Título do Filme"
            .Columns(1).HeaderText = "Total"

            .Columns(0).Width = 180
            .Columns(1).Width = 60
            'seleciona a linha inteira
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            'não permite seleção de multiplas linhas
            .MultiSelect = False
            ' exibe nulos formatados
            .DefaultCellStyle.NullValue = " - "
            'permite que o texto maior que célula não seja truncado
            .DefaultCellStyle.WrapMode = DataGridViewTriState.True
            'define o alinhamamento
            .Columns(0).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
            .Columns(1).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
        End With
    End Sub

O resultado pode ser visto na figura abaixo:

3- Consultando os clientes com mais pedidos

Para consultar os clientes com mais pedidos vamos incluir um novo formulário em nosso projeto.

No menu PROJECT clique em  Add Windows Forms e informe o nome frmClientesPedidos.vb;

A seguir inclua, a partir da ToolBox, os seguintes controles no formulário:

Disponha os controles no formulário conforme o leiaute abaixo:

No evento Load do formulário inclua o código que chama a rotina exibeClientes():

 Private Sub frmClientesPedidos_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        exibeClientes()
    End Sub

A rotina exibeClientes(), vista a seguir, usa a consulta LINQ para obter os clientes com mais filmes pedidos:

Private Sub exibeClientes()
        Try
            Using ctxFilmes = New CiaFilmesEntities()

                Dim pedidos = From ped In ctxFilmes.Pedidos.Include("Clientes")
                              Group ped By ped.Clientes.Nome Into Count(ped.ClienteId)
                              Order By Count Descending
                              Select New With {Nome, Count}

                dgvClientes.DataSource = pedidos.ToList
                formataGridView()

            End Using
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

A rotina formataGridView(), que já vimos anteriormente também é usada para formatar o controle DataGridView.

Abaixo vemos o resultado para esta consulta:

Com essas consultas meu objetivo foi mostrar como você pode consultar facilmente o banco de dados usando LINQ com Entity Frameweork.

Na próxima aula iremos concluir o módulo de administração criando os relatórios do sistema.

      Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti