LINQ - Prático e rápido II


Vou mostrar como usar os recursos do LINQ na linguagem C# de forma bem objetiva com um enfoque essencialmente prático dando o mínimo de teoria possível.

Vou adotar o estilo problema/solução onde é apresentando um problema e em seguida mostrado uma das soluções possíveis no caso usando LINQ.

Problema: 1- Como selecionar itens a partir de uma coleção realizando filtros ?

A teoria você vai encontrar no artigo : LINQ - Prático e rápido I

Solução - Usando LINQ para realizar consultas e filtros em coleções

Abra o Visual Basic 2010 Express Edition e crie um novo projeto no menu File-> New Project escolhendo o template Windows Application com o nome LINQ_ConsultaFiltros;

No formulário form1.vb inclua os seguintes controles:

  1. 1 TextBox - txtNome
  2. 1 Button - btnPesquisar
  3. 1 ListBox - lstbDados

Conforme o leiaute da figura abaixo:

Agora clique no ícone View Code ( )da janela Solution Explorer e vamos definir o código da aplicação:

1- Definindo a coleção com os nomes dos clientes:

Dim clientes() As String = {"Macoratti", "Jefferson", "Miriam", "Janice", "Marcia", "Mario", "Bianca", "Yuri"}

2- No evento Click do botão Pesquisar vamos chamar a rotina filtraDados();

Private Sub btnPesquisar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPesquisar.Click
        filtraDados()
End Sub

3- Da mesma forma no evento TextChanged do controle txtNome vamos chamar a rotina filtraDados();

Private Sub txtNome_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtNome.TextChanged
        filtraDados()
End Sub

4- Vamos agora criar o código para a rotina filtraDados():

 Private Sub filtraDados()

        Dim consulta = From c In clientes
                             Order By c
                             Where c.StartsWith(txtNome.Text)
                             Select c

        preencheLista(consulta)
    End Sub

A consulta LINQ seleciona da coleção os nomes iniciados com a letra que for informada no controle TxtNome.Text;

Estamos usando função StartWith que determina se o inicio da string coincide com a string informada. Além dessas funções podemos usar outra funções conforme mostra a figura abaixo obtida do Intellisense:

No exemplo do artigo eu vou usar também a função Contains que indica se a string especificada
ocorre na string de origem.

A sintaxe neste caso seria:

Dim consulta = From c In clientes
                       Order By c
                       Where c.Contains(txtNome.Text)
                       Select c

Observe que não foi preciso eu utilizar o caractere (_) de quebra de linha na consulta LINQ visto que na versão 2010 O VB da suporte a múltiplas linhas.

5- Para preencher o controle ListBox (lstbDados) devemos definir a rotina preencheLista() passando a consulta LINQ:

Private Sub preencheLista(ByVal nomes As IEnumerable)
        lstbDados.Items.Clear()
        For Each nome In nomes
            lstbDados.Items.Add(nome)
        Next
    End Sub

Executando o projeto e digitando um caractere na caixa de texto teremos a execução da consulta LINQ obtendo e filtrando os dados e exibindo-os no ListBox conforme a figura abaixo;

Continuando a digitar teremos a execução novamente do filtro via consulta LINQ:
Usando uma expressão lambda na consulta LINQ

O que são Expressões Lambda ?

As expressões lambda foram incluídas no VS/VB 2008 para dar suporte a consultas LINQ. As cláusulas Where são assim compiladas como expressões lambdas e chamadas em itens aplicáveis do seu dataset. Podem ser consideradas uma forma de delegate que pode passar ou retornar outra função.

Nota: Delegates permitem que uma classe use métodos de outra classe. Para saber mais sobre delegates leia o meu artigo: Usando Delegates

No LINQ as expressões lambda são usadas para realizar ações sobre listas de objetos e com extensões de métodos.

Uma expressão lambda é então uma função sem nome que calcula e retorna um valor único e podem ser usadas em qualquer lugar que um tipo delegate for válido.

Vamos agora usar uma expressão lambda na consulta LINQ para obter o mesmo resultado. Para o nosso exemplo a consulta ficaria expressa da seguinte forma:

Dim consulta = clientes.Where(Function(nome) nome.Contains(txtNome.Text)).OrderBy(Function(nome) nome)

A sintaxe das expressões lambdas

A sintaxe de uma expressão lambda lembra a de uma função padrão. As diferenças são as seguintes:

- Uma expressão lambda não tem um nome.
- Expressões lambda não podem ter modificadores, como
Overloads ou Overrides.
- Expressões lambda não usam uma cláusula As para designar o tipo de retorno da função. Em vez disso, o tipo é inferido do valor que o corpo da expressão lambda avalia. Por exemplo, se o corpo da expressão lamba for
Where cli.City = "Brazil", seu tipo de retorno é Boolean.
- O corpo da função deve ser uma expressão, não uma instrução. O corpo pode consistir de uma chamada para um procedimento de função, mas não uma chamada para um procedimento sub.
- Nas expressões lambadas não existe uma instrução
Return. O valor retornado pela função é o valor da expressão no corpo da função.
- Nas expressões lambdas não existe um instrução
End Function.
- Ou todos os parâmetros devem ter tipos de dados especificados ou todos devem ser inferidos.
- Parâmetros opcionais e
ParamArray não são permitidos.
- Parâmetros genéricos não são permitidos.

Como resultado dessas restrições e das maneiras pelas quais as expressões lambda são usadas, elas geralmente são simples , curtas e pouco complexas.

Uma expressão lambda compartilha seu contexto com o método no qual ela está definida. Ela tem os mesmos direitos de acesso que qualquer código escrito no método que a contém. Isso inclui acesso a variáveis de membro, funções e sub-rotinas , parâmetros e variáveis locais no método que a contém.

Podemos dizer que sem as expressões lambdas o LINQ não seria o mesmo.

E por enquanto estamos conversados...

Pegue o projeto completo aqui:  LINQ_ConsultaFiltros.zip

Aguarde mais artigos sobre LINQ usando a linguagem VB .NET.

Referências:


José Carlos Macoratti