VB .NET - Usando operadores LINQ
Hoje vou mostrar como usar alguns operadores LINQ usando a linguagem VB .NET. |
A LINQ é que ela foi criada com o objetivo de simplificar consultas a informações na memória em coleções como listas e arrays, bem como informações armazenadas em base de dados , documentos XML , arquivos e outras fontes de dados. Ela realiza uma mapeamento objeto Relacional de forma que a o acesso a dados é feito através do framework LINQ e as instruções SQL são geradas implicitamente.
Neste artigo eu mostrar como usar os operadores ThenBy, Any, Concat, Cast, Distinct, ElementAt, Repeat, Last e Except.
Esses são apenas alguns dos muitos operadores que a LINQ tem em seu arsenal. Veja abaixo uma relação dos operadores:
Operador | Lazy ? | Descrição |
---|---|---|
Aggregate | No | Aplica uma função a uma seqüência , originando um valor único |
All | No | Aplica uma função a uma seqüência para verificar se todos os elementos satisfazem a função. |
Any | No | Aplica uma função a uma seqüência para verificar se qualquer elemento satisfaz a função. |
Average | No | Calcula a média de um seqüência numérica. |
Concat | Yes | Produz a concatenação de duas seqüências S1 e S2. |
Contains | No | Procura a seqüência para verificar se a mesma contem um dado elemento. |
Count | No | Conta o numero de elementos em uma seqüência , originando um resultado inteiro. |
DefaultIfEmpty | Yes | Data uma seqüência S, produz S ou a seqüência com o valor padrão se S estiver vazia. |
Distinct | Yes | Retorna a seqüência com valores duplicados eliminados. |
ElementAt | No | Retorna o i-ésimo elemento de uma seqüência. |
ElementAtOrDefault | No | Retorna o i-ésimo elemento de uma seqüência se a seqüência ou o padrão se a seqüência estiver vazia. |
Empty | Yes | Produz uma seqüência vazia. |
EqualAll | No | Compara duas seqüências por igualdade. |
Except | Yes | Dada duas seqüências S1 e S2, retorna o conjunto diferença S1 S2. |
First | No | Retorna o primeiro elemento da seqüência. |
FirstOrDefault | No | Retorna o primeiro elemento da seqüência, ou o valor padrão se a seqüência esta vazia. |
GroupBy | Yes | Agrupa os elementos de uma seqüência pela chave. |
GroupJoin | Yes | Realiza uma junção de duas seqüências S1 e S2 produzindo um resultado hierárquico. |
Intersect | Yes | Dada duas seqüências S1 e S2, retorna o conjunto intersecção de S1 e S2 |
Join | Yes | Realiza uma junção tradicional interna de duas seqüências S1 e S2. |
Last | No | Retorna o último elemento de uma seqüência. |
LastOrDefault | No | Retorna o último elemento de uma seqüência ou o valor padrão se a seqüência estiver vazia. |
LongCount | No | Conta o número de elementos em uma seqüência, produzindo um resultado do tipo long. |
Max | No | Retorna o valor máximo de uma seqüência. |
Min | No | Retorna o valor mínimo de uma seqüência |
OfType | Yes | Produz os elementos de uma seqüência que coincide com um dado tipo. |
OrderBy | Yes | Ordena uma seqüência de elementos pela chave na ordem ascendente. |
OrderByDescending | Yes | Ordena uma seqüência de elementos pela chave na ordem descendente. |
Range | Yes | Produz uma seqüência de inteiros em um dado intervalo. |
Repeat | Yes | Produz uma seqüência de valores pela repetição de um dado valor n vezes. |
Reverse | Yes | Inverte os elementos de um seqüência. |
Select | Yes | Aplica a função de projeção a uma seqüência , originando uma nova seqüência. |
Single | No | Retorna o único elemento de um seqüência única. |
SingleOrDefault | No | Retorna o único elemento de uma seqüência , ou valor padrão se estiver vazia. |
Skip | Yes | Pula o primeiro elemento de uma seqüência , produzindo os elementos restantes. |
SkipWhile | Yes | Data uma função F e seqüência S, pula os elementos iniciais de S onde F é verdadeira. |
Sum | No | Calcula a soma de uma seqüência numérica. |
Take | Yes | Produz os primeiros n elementos de uma seqüência. |
TakeWhile | Yes | Dada uma função F e uma seqüência S, produz os elementos iniciais de S onde F for verdadeira. |
ThenBy | Yes | Toma uma seqüência ordenada e produz uma secundária , na ordem ascendente. |
TheyByDescending | Yes | Toma uma seqüência ordenada e produz uma secundária , na ordem descendente. |
ToArray | No | Percorre uma seqüência, capturando os resultados em um array. |
ToDictionary | No | Percorre uma seqüência, capturando os resultados em um Dictionary<K, V>. |
ToList | No | Percorre uma seqüência, capturando os resultados em uma List<T>. |
ToLookup | No | Percorre uma seqüência, capturando os resultados em um Lookup<K, IEnumerable<V>>. |
ToSequence | Yes | Converte uma seqüência em uma seqüência IEnumerable para usar com consulta padrão. |
Union | Yes | Dada duas seqüências S1 e S2 retorna o conjunto união de S1 e S2. |
Where | Yes | Aplica uma função Booleana a uma seqüência, produzindo uma sub seqüência. |
Obs: Lazy é um atributo que significa 'quanto mais tarde melhor' e tem o objetivo de carregar um item sob demanda. (Lazy Loading)
Recursos usados :
Criando o projeto no Visual Studio
Abra o Visual Studio 2013 Express Edition for windows desktop e clique em New Project;
Selecione a linguagem Visual Basic e o template Windows Forms Application;
Informe o nome VBNET_LINQ_Operadores ou outro nome de sua preferência e clique OK.
A seguir inclua a partir da ToolBox os seguintes controles no formulário form1.vb:
Disponha os controles no formulário conforme a figura abaixo:
Vamos criar 3 arrays, dois arrays de string e um array de inteiros para isso vamos declarar as variáveis abaixo no início do formulário:
Dim numerosString() As StringAgora para criar os arrays vamos definir o código abaixo no evento Click do botão de comando Gerar Array :
Private Sub btnGerarArrayNumeros_Click(sender As Object, e As EventArgs) Handles btnGerarArrayNumeros.Click
Dim separadores() As String = {",", ".", "!", "?", ";", ":", " "}
Try
nomes = txtNomes.Text.Split(separadores, StringSplitOptions.RemoveEmptyEntries)
numerosString = txtNumeros.Text.Split(separadores, StringSplitOptions.RemoveEmptyEntries)
numeros = Array.ConvertAll(numerosString, Function(str) Int32.Parse(str))
HabilitaControlesButton()
btnGerarArrayNumeros.Enabled = False
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
|
Dessa forma os arrays serão gerados com os valores informados nos controles TextBox.
Observe que primeiro eu estou gerando dois arrays de string e depois usando o método ConvertAll da classe Array estou convertendo o array de strings numerosString para um array de inteiros em numeros.
Quando o usuário clicar no botão Gerar Array, após a geração dos arrays nomes() e numeros() a rotina HabilitaControlesButton() será chamada para habilitar a propriedade Enabled dos botões.
A seguir temos o código desta rotina:
Private Sub HabilitaControlesButton()
For Each P As Control In Controls
If TypeOf P Is TableLayoutPanel Then
For Each ctrl As Control In P.Controls
If TypeOf ctrl Is Button Then
CType(ctrl, Button).Enabled = True
End If
Next
End If
Next
End Sub
|
Esse código percorre o controle TableLayoutPanel e para cada controle do tipo Button define sua propriedade Enabled como igual a True,
Criamos também uma rotina chamada ajeitaListBox() que recebe um controle button como parâmetro. Seu código esta abaixo:
Private Sub ajeitaListBox(ctrl As Button)
lbResultado.Items.Clear()
lbResultado.Items.Add(ctrl.Tag)
lbResultado.Items.Add("")
End Sub
|
Este código limpa o controle ListBox e inclui um item no controle referente ao texto que esta na propriedade Tag do respectivo controle e a seguir inclui um item vazio.
Usando os operadores LINQ
Agora vamos mostrar a definição e como usar cada operador LINQ. Iremos definir o código no evento Click de cada um dos 9 Buttons.
1- Operador ThenBy
''' <summary>
''' Executa um ordenação subseqüente dos elementos em uma seqüência em ordem crescente.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnThenBy_Click(sender As Object, e As EventArgs) Handles btnThenBy.Click
ajeitaListBox(btnThenBy)
Dim consulta As IEnumerable(Of String) = nomes.OrderBy(Function(nome) nome.Length).ThenBy(Function(nome) nome)
For Each _nome As String In consulta
lbResultado.Items.Add(_nome)
Next
End Sub
|
O exemplo esta ordenando o array nomes pelo tamanho do nome - nome.Length
Resultado:
2- Operador Any
''' <summary>
''' O operador Any numera a seqüência de origem e retorna true se qualquer elemento satisfaz
''' o critério determinado pelo predicado
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnAny_Click(sender As Object, e As EventArgs) Handles btnAny.Click
ajeitaListBox(btnAny)
Dim anyNumeros As Boolean = New Integer() {2, 3, 4, 5, 6, 7, 8}.Any(Function(n) n = 10)
Dim anyNomes As Boolean = New String() {"Paulo", "Jose", "Carlos", "Pedro", "Maria", "Macoratti"}.Any(Function(n) n = "Jose")
lbResultado.Items.Add(anyNumeros)
lbResultado.Items.Add(anyNomes)
End Sub
|
A primeira consulta verifica se o número 10 esta no array {2, 3, 4, 5, 6, 7, 8} - resultado será False
A segunda consulta verifica se o nome 'Jose' esta no array {"Paulo", "Jose", "Carlos", "Pedro", "Maria", "Macoratti"} - resultado será True
3- Operador Concat
''' <summary>
''' O operador Concat concatena duas seqüências.
''' Ele retorna todos os elementos da primeiro seqüência, em seguida, todos os elementos da segunda seqüência.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnConcat_Click(sender As Object, e As EventArgs) Handles btnConcat.Click
ajeitaListBox(btnConcat)
Dim sequencia2 As Integer() = {555, 666, 777, 888, 999}
Dim resultado As IEnumerable(Of Integer) = numeros.Concat(sequencia2)
For Each valor As Integer In resultado
lbResultado.Items.Add(valor)
Next
End Sub
|
Resultado:
4- Operador Cast
''' <summary>
''' O operador Cast realiza um cast no elemento da sequencia para um tipo dado.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnCast_Click(sender As Object, e As EventArgs) Handles btnCast.Click
ajeitaListBox(btnCast)
' Cria um ArrayList e incluir itens
Dim frutas As New System.Collections.ArrayList()
frutas.Add("Laranja")
frutas.Add("Manga")
frutas.Add("Abacate")
frutas.Add("Banana")
' chama o Cast(Of String) para converter os elementos do ArrayList para strings.
' Então chama Select() para projetar as string como resultado
Dim consulta As IEnumerable(Of String) = _
frutas.Cast(Of String)().Select(Function(fruta) fruta)
Dim saida As New System.Text.StringBuilder
For Each fruta As String In consulta
saida.AppendLine(fruta & ", ")
Next
lbResultado.Items.Add(saida)
End Sub
|
O operador Cast converte os elementos do ArrayList para String.
O resultado será: Laraja,Manga,Abacate,Banana
5- Operador Distinct
''' <summary>
''' Elimina valores duplicados em uma sequência
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnDistinct_Click(sender As Object, e As EventArgs) Handles btnDistinct.Click
ajeitaListBox(btnDistinct)
Dim consulta = (From s In nomes).Distinct()
For Each nome As [String] In consulta
lbResultado.Items.Add(nome)
Next
End Sub
|
O operador Distinct elimina elementos duplicados na sequência.
Resultado:
6- Operador ElementAt
''' <summary>
''' Retorna um elemento em um dado índice da sequência
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnElementAt_Click(sender As Object, e As EventArgs) Handles btnElementAt.Click
ajeitaListBox(btnElementAt)
Dim elemento As Integer = numeros.ElementAt(5)
lbResultado.Items.Add("O elemento no índice 5 é : " & elemento.ToString)
End Sub
|
O operador ElementAt e retorna um elemento para um dado índice na sequência.
O resultado será o elemento com índice igual a 5 : 58
7- Operador Repeat
''' <summary>
''' Repete um valor especificado um determinado número de vezes
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnRepeat_Click(sender As Object, e As EventArgs) Handles btnRepeat.Click
ajeitaListBox(btnRepeat)
For Each i As Integer In Enumerable.Repeat(7, 6)
lbResultado.Items.Add(i & " ")
Next
End Sub
|
O operador Repeat repete um valor especificado um determinado número de vezes.
Resultado :
8- Operador Last
''' <summary>
''' Retorna o último elemento da sequência
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnLast_Click(sender As Object, e As EventArgs) Handles btnLast.Click
ajeitaListBox(btnLast)
Dim ultimoNumero As Integer = numeros.Last()
Dim ultimoPar As Integer = numeros.Last(Function(n) n Mod 2 = 0)
lbResultado.Items.Add("Último número : " & ultimoNumero.ToString)
lbResultado.Items.Add("Último número par : " & ultimoPar.ToString)
End Sub
|
O operador Last retorna o último elemento da sequência que atenda o critério definido.
Estamos realizando uma consulta para retonar o último número e o último número par.
Resultado :
9- Operador Except
''' <summary>
''' Retorna elementos da primeira sequência que não estão na segunda sequência
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnExcept_Click(sender As Object, e As EventArgs) Handles btnExcept.Click
ajeitaListBox(btnExcept)
Dim sequencia2 As Integer() = {3, 4, 5, 6, 7, 8}
lbResultado.Items.Add("sequencia2 = 3, 4, 5, 6, 7, 8")
Dim diferenca1 As IEnumerable(Of Integer) = numeros.Except(sequencia2)
Dim diferenca2 As IEnumerable(Of Integer) = sequencia2.Except(numeros)
lbResultado.Items.Add("Não estão na sequencia2 -----------------")
For Each i As Integer In diferenca1
lbResultado.Items.Add(i)
Next
lbResultado.Items.Add("Não estão em numeros -----------------")
For Each i As Integer In diferenca2
lbResultado.Items.Add(i)
Next
End Sub
|
O operador Except retorna os elementos da primeira sequência que não estão na segunda sequência.
Estamos fazendo duas consultas: Uma verificando quais elementos da primeira sequência não estão na segunda e na outra invertemos as sequências:
Resultado :
Pegue o projeto completo aqui : VBNET_LINQ_Operadores.zip
Até o próximo artigo...
João 6:35 Declarou-lhes Jesus. Eu sou o pão da
vida; aquele que vem a mim, de modo algum terá fome, e quem crê em mim jamais
terá sede.
João 6:36 Mas como já vos disse, vós me tendes
visto, e contudo não credes.
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ?
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#