Primeiras aulas do curso Entity LinQ parte 2: Store Procedures e consultas com o LinQPad

Entity LinQ parte 2: Store Procedures e consultas com o LinQPad

Aprenda a criar relatórios com paginação - 1- Introdução

Para o Curso LINQ: Crie queries poderosas em C# parte 2 é fortemente aconselhável cursar a primeira parte do curso, disponível aqui.

No presente curso serão abordados os seguintes pontos:

Um Relatório de Vendas é repaginado quando é quebrado em páginas para melhorar a apresentação dos resultados. Tradicionalmente os resultados são mostrados de uma única vez, mas na forma repaginada eles são disponibilizados em diferentes páginas.

Nessa etapa também vamos verificar como criar um relatório utilizando diferentes métodos. Na sequência vamos aprender a calcular o número de registros que devem ser pulados para atingir uma determinada página e, por fim, utilizaremos uma função matemática da biblioteca C#, a Ceiling.

Nesta parte abordaremos o conceito de consulta. Vamos simplificar consultas tornando-as menores e também vamos extrair de uma consulta maior, uma menor. Ainda, veremos sobre a aplicação de subconsultas em vários pontos da consulta LINQ, por exemplo, nas cláusulas where, group by e select.

Neste trecho a proposta é verificar os produtos mais vendidos da loja, para isto, utilizaremos o conceito de projeção de dados e o método Sum. Na sequência vamos somar as vendas por produto por mio de um agrupamento. Caso um produto não possua nenhuma venda registrada, vamos nos deparar com um problema, pois chegaremos a um momento no qual ocorrerá uma exceção e aprenderemos a contornar essa situação!

Veremos que algumas expressões se repetem na consulta e acabaremos utilizando um operador que vai permitir a criação de variáveis internas a consulta. No final vamos construir uma consulta, executá-la, pegar seu resultado e utilizá-la em outra consulta.

Nesta parte aprenderemos sobre análise de afinidade ou análise de carrinho. A análise de carrinho mostra, quando fazemos uma compra na Internet, produtos similares aos que já adquirimos. Por exemplo, ao comprar uma impressora produtos como cartuchos são mostrados. Para gerar o relatório de análise de afinidade utilizaremos o self join.

Vamos aprender sobre a diferença entre a execução adiada e a execução imediata. Ao final desta parte veremos como utilizar uma execução imediata trazendo os resultados de uma consulta LINQ para uma lista em memória. Analisaremos a possibilidade de utilizar um cache para guardar os dados e não precisar executá-los o tempo inteiro na consulta.

Veremos uma situação em que a área de marketing solicita para nós a criação de códigos de tipo QRCode dentro de uma consulta LINQ. Assim, vamos perceber que a execução dessa consulta será um pouco mais demorada, pois transformar uma informação em imagem que representa QRCode demora um pouco! Vamos descobrir como medir o tempo de execução da consulta e também como diminuí-lo. Depois, trabalharemos com stored procedures dentro de consultas LINQ do Entities. No final, vamos realizar uma tarefa secundária que agrupará uma consulta em dois campos diferentes.

Na parte final do curso vamos aprender sobre o LINQPad que é uma ferramenta já bastante madura e que facilita o trabalho de quem desenvolve consultas com LINQ. Veremos que o LINQPad permite a execução de códigos C# em geral e não apenas códigos que possuam uma consulta LINQ. Iniciaremos trabalhando com expressões simples e veremos que é possível abrir arquivos do C# dentro do LINQPad modificando a extensão para um formato que ele conheça. Aprenderemos a pegar uma consulta com sintaxe de consulta e gerar uma sintaxe de método (ou sintaxe lambda). Por fim, vamos gerar uma consulta a partir do xml e configuraremos também uma consulta LINQ do Entities.

Aprenda a criar relatórios com paginação - 2 - Linq to entities paginado

O novo pedido do cliente é: produzir um relatório detalhado de vendas do sistema. O objetivo é que o relatório seja paginado, portanto, é preciso quebrar o relatório em páginas diferentes e cada uma deve conter um máximo de dez linhas.

Já vimos que uma venda é representada, no sistema, usando a Nota Fiscal. Desta maneira, no arquivo Program.cs, vamos inserir uma classe e dentro dela colocaremos o using (var contexto = new AluraTunesEntities()) e a partir do contexto, nós vamos trazer a NotasFiscais. Portanto, acrescentaremos o from nf in contexto.NotasFiscais e abaixo o select new. Feito isso, é preciso adicionar a variável: var query =. Ao final, iremos inserir a impressão do resultado, portanto, colocamos foreach (var nf in query) e Console.WriteLine(nf.Total). O código ficará da seguinte maneira:

class Program 
{
    static void Main(string[] args)
    {
        using (var contexto = new AluraTunesEntities())
        {
            var query =
            from nf in contexto.NotasFiscais
            select new;

            foreach (var nf in query)
            {
                Console.WriteLine(nf.Total);
            }
        }
    }
}

Ao rodarmos o código, serão trazidos apenas os valores das Notas Fiscais.

Agora, vamos expandir o relatório inserindo mais colunas nele!

Para fazer isso, vamos inserir um objeto anônimo e dessa forma o relatório será exibido. Assim, adicionamos: Numero = nf.NotaFiscalId, Data = nf.DataNotaFiscal, Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome e, por fim, o Total = nf.Total. O código ficará da seguinte maneira:

var query =
from nf in contexto.NotasFiscais
select new;
{
Numero = nf.NotaFiscalId,
Data = nf.DataNotaFiscal,
Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
Total = nf.Total
}

Ao acrescentarmos estas informações é preciso inseri-las também no Console.WriteLine(). Vamos, portanto, adicionar: nf.Numero, nf.Data, nf.Clientenf, nf.Total. Ao fazer isso teremos um total de 4 colunas a serem impressas. Falta inserir uma string de formatação a fim de indicar a posição das colunas: "{0}\t{1}\{2}\{3}":

ConsoleWriteLine("{0}\t{1}\{2}\{3}", nf.Numero, nf.Data, nf.Clientenf, nf.Total)

Ao rodarmos o código teremos as quatro colunas!

Falta paginar o relatório e para que isso aconteça é necessário, primeiro, quebrar o relatório em páginas. Portanto, vamos iniciar mostrando apenas a primeira. Para que isso ocorra é preciso utilizar um filtro que limite o número de linhas mostradas em cada página, no caso, dez linhas. Desta forma, acrescentaremos uma query e junto dela vamos inserir um comando, o Take() que possui justamente a função de pegar. Como queremos que sejam selecionadas dez linhas, passaremos o valor 10:


query = query.Take(10),

Com isso, a aplicação mostrará a primeira página e nela aparecem apenas as dez linhas que filtramos. Lembrando que para a informação seguir aparecendo é preciso inserir o Console.ReadKey(). Por enquanto o código está com o seguinte aspecto:

class Program 
{
    static void Main(string[] args)
    {
        using (var contexto = new AluraTunesEntities())
        {
            var query =
            from nf in contexto.NotasFiscais
            select new;
            {
            Numero = nf.NotaFiscalId,
            Data = nf.DataNotaFiscal,
            Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
            Total = nf.Total
            };

            query = query.Take(10),

            foreach (var nf in query)
            {
                ConsoleWriteLine("{0}\t{1}\{2}\{3}", nf.Numero, nf.Data, nf.Clientenf, nf.Total);
            }

            Console.ReadKey();
        }
    }
}

É preciso refatorar o 10, pois, a boa prática indica que é melhor extrair uma variável ou constante que possibilite fazer a modificação uma única vez e em um mesmo local. Portanto, basta selecionar o 10 e usar o comando "Ctrl + .". Aparecerão algumas possibilidades de refatoração, das quais selecionaremos o Introduce local constant for '10'. Depois, renomearemos a constante para TAMANHO_PAGINA. O maiúsculo será utilizado, pois este é um padrão de constante. Teremos o seguinte:

            select new
            {
            Numero = nf.NotaFiscalId,
            Data = nf.DataNotaFiscal,
            Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
            Total = nf.Total
            };

            query = query.Take(TAMANHO_PAGINA);

            foreach (var nf in query)
            {
                ConsoleWriteLine("{0}\t{1}\{2}\{3}", nf.Numero, nf.Data, nf.Clientenf, nf.Total);
            }

Vamos reposicionar o const int TAMANHO_PAGINA = 10; para baixo do static void Main(string[] args).

Ao rodarmos a aplicação, nada estará quebrado! Agora, para trazer a segunda página é preciso pular a quantidade de linhas equivalente a primeira página. Para fazer isso é preciso modificar a query. Portanto, utilizamos o comando equivalente ao ato de saltar: o skip(). Para este comando, nós podemos passar a constante que determinamos anteriormente, a TAMANHO_PAGINA.

query = query.Skip(TAMANHO_PAGINA);

query = query.Take(TAMANHO_PAGINA);

Porém, um erro ocorre! O skip só pode ser utilizado em consultas ordenadas, o que não é o caso.

Para fazer a consulta funcionar é preciso ordená-la. Dessa maneira, adicionamos o orderby e junto disso inserimos também o NotaFiscalId que indica por onde a ordenação deve se guiar:

var query
from nf in contexto.NotasFiscais
orderby nf.NotaFiscalId
select new
    {
        Numero = nf.NotaFiscalId,
        Data = nf.DataNotaFiscal,
        Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
        Total = nf.Total
    };

Ao rodar o código o resultado é uma ordenação conforme o número da nota fiscal. Inclusive, os dez primeiros resultados não serão mostrados, pois correspondem a primeira página.

Por fim, antes que todas as páginas do relatório sejam impressas é preciso realizar algumas modificações! Por exemplo, para chegar a terceira página, quantas linhas devem ser puladas? Neste caso, é preciso utilizar uma conta que nos auxilie nesta tarefa! Vamos pensar um pouco: o número que saltamos de páginas é o número da página multiplicado pelo número de linhas de cada página. Mas, as páginas não começam a contar a partir de 1 e, sim, do 0, uma vez que a página 1 não precisa que sejam puladas linhas.

A lógica é a seguinte:

PÁGINA      SALTAR
1            0 = 0X10 = 0X
2            10 = 1X10 = 1X
3            20 = 2X10 = 2X
4             30 = 3X30 = 3X

A fórmula que encontrada será a seguinte:

(página - 1) x Tamanho Página

No código nós vamos adicionar o seguinte:

numeroDePulos = (numeroPagina - 1) * TAMANHO_PAGINA;

Teremos:

numeroDePulos = (numeroPagina - 1) * TAMANHO_PAGINA

query = query.Skip(TAMANHO_PAGINA);

query = query.Take(TAMANHO_PAGINA);

A variável numeroPagina, entretanto, ainda não existe! Por isso, é preciso criá-la:

int numeroPagina = 1;
int numeroDepulos = (numeroPagina - 1) * TAMANHO_PAGINA;

query = query.Skip(TAMANHO_PAGINA);

query = query.Take(TAMANHO_PAGINA);

Vamos deslocar o int numeroPagina = 1; para antes da var query. Ao fazer isso, modificaremos o TAMANHO_PAGINA por numeroDePulos:

int numeroPagina = 1;

var query
from nf in contexto.NotasFiscais
orderby nf.NotaFiscalId
select new
    {
        Numero = nf.NotaFiscalId,
        Data = nf.DataNotaFiscal,
        Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
        Total = nf.Total
    };


int numeroDepulos = (numeroPagina - 1) * TAMANHO_PAGINA;

query = query.Skip(numeroDePulos);

query = query.Take(TAMANHO_PAGINA);

Ao inserirmos as modificações podemos verificar que a primeira página estará funcionando conforme esperado. Ao modificar o int numeroPagina = 1; para int numeroPagina = 2; observamos as linhas de 11 a 20 e assim por diante!

Após ordenar a consulta, é preciso, finalmente, imprimir o relatório inteiro. Primeiro vamos refatorar o código, pois ele já está muito grande. Isto é, vamos extrair uma função que deve imprimir uma página. Assim, selecionamos o código e damos um "Ctrl + ." e aparecerá a opção "Extract Method". O novo método receberá o nome de ImprimirPagina. Nosso código ficará da seguinte maneira:

const int TAMANHO_PAGINA = 10;

using (var contexto = new AluraTunesEntities())
{
    int numeroPagina = 3;

    ImprimirPagina(TAMANHO_PAGINA, contexto, numeroPagina);

    Console.ReadKey();
}

O problema é que, da maneira como está escrito, parece que a impressão deve ser feita apenas para uma página. Nosso objetivo é que as páginas sejam impressas uma por uma até o final. Portanto, primeiro, vamos mensurar a quantidade de linhas totais. Para isso, vamos introduzir contexto.NotasFiscais.Count(), no qual o método Count() é responsável pela contagem. O resultado disso nós armazenaremos na variável numeroNotasFiscais. Falta, ainda, calcular a quantidade total de páginas do relatório e para chegar a este número vamos pegar o número de linhas do relatório e dividir pelo tamanho da página: numeroNotasFiscais /TAMANHO_PAGINA. Isso nós armazenaremos na variável numeroPaginas. Nosso código ficará da seguinte maneira:

const int TAMANHO_PAGINA = 10;

using (var contexto = new AluraTunesEntities())
{
    int numeroPagina = 3;

    var numeroNotasFiscais= contexto.NotasFiscais.Count();
    var numeroPaginas = numeroNotasFiscais / TAMANHO_PAGINA;

    ImprimirPagina(TAMANHO_PAGINA, contexto, numeroPagina);

    Console.ReadKey();
}

O problema é que a conta não resulta em um número correto de páginas. É preciso arredondar os números e a fim de solucionar o impasse vamos utilizar um método presente na biblioteca, o Math.Ceiling(). A palavra ceiling, em inglês , significa teto, isto é, o arredondamento será para cima. Porém, ao utilizar a função, Math.Ceiling() também é preciso converter a fórmula para decimal para que ela de fato funcione. Teremos: Math.Ceiling((decimal)NumeroNotasFiscais / TAMANHO_PAGINA).

Ainda falta imprimir as páginas do relatório e para fazer isso, nós vamos criar um laço for e junto dele nós inserimos a variável p que equivale a páginas. Assim, p = 1; p < numeroPaginas; p++. Dentro do for nós colocamos o ImprimirPagina(TAMANHO_PAGINA, contexto, numeroPagina);. Teremos o seguinte:

using (var contexto = new AluraTunesEntities())
{
    int numeroPagina = 3;

    var numeroNotasFiscais= contexto;NotasFiscais.Count();
    var numeroPaginas = numeroNotasFiscais / TAMANHO_PAGINA;

    for (var p = 1; p < numeroPaginas; p++)
    {

        ImprimirPagina(TAMANHO_PAGINA, contexto, numeroPagina);
    }

    Console.ReadKey();
}

O problema disso é que não especificamos que p deve pegar o número de páginas final, portanto, é preciso dizer que p é menor ou igual a numeroPaginas:

for (var p = 1; p <= numeroPaginas; p++)

Falta, substituir o numeroPagina que passamos para o ImprimirPagina por p. Teremos:

ImprimirPagina(TAMANHO_PAGINA, contexto, p);

Por fim, removemos o int numeroPagina = 3 que estará sobrando!

Nosso código ficará da seguinte maneira:

using (var contexto = new AluraTunesEntities()) {

    var numeroNotasFiscais= contexto.NotasFiscais.Count();
    var numeroPaginas = numeroNotasFiscais / TAMANHO_PAGINA;

    for (var p = 1; p < numeroPaginas; p++)
    {

        ImprimirPagina(TAMANHO_PAGINA, contexto, p);
    }

    Console.ReadKey();
}

Ao rodar a aplicação teremos um relatório que mostra da linha 1 a 412, que é a última que aparece no relatório. O problema é que a impressão aparece em sequência, então, não saberemos onde cada linha está situada. Para resolver a questão, vamos inserir uma última instrução, antes da seguinte linha:

foreach (var nf in query)

Nós colocamos o ConsoleWriteLine() e passamos para isso o "Numero da Pagina, {0}", numeroPagina. Teremos:

query = query.Skip(NumeroDePulos);

query = query.Take(TAMANHO_PAGINA);

Console.WriteLine();
Console.WriteLine("Numero da Pagina, {0}", numeroPagina);

Ao rodar a aplicação o resultado é, finalmente, uma divisão por páginas:

Acabamos de aprender a fazer a impressão de um relatório paginado. Este é um sistema extremamente utilizado! Por exemplo, na caixa de e-mails do Gmail, pois podemos visualizar diferentes páginas, inclusive pulando-as sem precisar passar por todas as páginas anteriores!

Aprenda a criar relatórios com paginação - 3 - Subconsulta

Neste curso trabalharemos com um cliente que possui uma loja on-line. A partir dela ele vai realizar diversos pedidos para que relatórios sejam produzidos.

O primeiro pedido do cliente é gerar um relatório que traga as vendas que possuem valor acima da média. Para fazer isso vamos iniciar com uma consulta simples, portanto, vamos introduzir a var query = e dentro disso colocamos o from nf in contexto.NotasFiscais e o select nf. Como é preciso imprimir o conteúdo da consulta, adicionamos o foreach (var nota in query) e o Console.WriteLine(notaFiscal.Total). Por fim, acrescentamos o Console.ReadKey() para que a janela do resultado não seja imediatamente fechada. Teremos o seguinte código:

var query = 
from nf in contexto.NotasFiscais
select nf;

foreach (var notaFiscal in query)
{
    Console.WriteLine(notaFiscal.Total);
}

Console.ReadKey();

Ao rodar a aplicação teremos uma listagem com os valores totais de notas.

O resultado é uma consulta simples que gera um relatório igualmente simples! A partir de agora vamos incrementá-lo para que traga campos específicos. Para fazer isso modificamos o select nf para select new e dentro deste último incluímos os dados desejados:

Número de nota: Numero = nf.NotaFiscalId Data de nota: Data = nf.DataNotaFiscalId Cliente: Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome Valor: nf.Total

No campo Cliente adicionamos o primeiro nome e também o sobrenome, por isso introduzimos nf.Cliente.PrimeiroNome e nf.Cliente.Sobrenome, respectivamente. O código fica da seguinte maneira:

var query = 
from nf in contexto.NotasFiscais
select new
{
    Numero = nf.NotaFiscalId,
    Data = nf.DataNotaFiscalId,
    Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
    Valor = nf.Total

};

Ao incluir estas informações é preciso alterar o relatório para trazer todos os campos descritos acima. Assim, incluímos notaFiscal.Numero, notaFiscal.Data, notaFiscal.Cliente e notaFiscal.Valor . Junto disso adicionamos uma string de formatação, a "{0}\t{1}\{2}\t{3}", que refere-se as quatro colunas da consulta. Nosso código fica da seguinte maneira:

foreach (var notaFiscal in query)
{

 Console.WriteLine("{0}\t{1}\{2}\t{3}", 
    notaFiscal.Numero,
    notaFiscal.Data,
    notaFiscal.Cliente,
    notaFiscal.Valor);
}

Rodando a aplicação o resultado é um relatório que traz os dados de número, data, cliente e valor:

Feito esse procedimento de incluir as diversas informações que nos interessam, vamos seguir com nosso objetivo que é pegar as notas fiscais com valores de venda acima da média. Para encontrar tais itens é preciso criar um filtro, portanto, utilizamos o where nf.Total. Para obter a média inserimos um contexto.NotasFiscais e junto disso acrescentamos o método Average() e passamos para ele a expressão n -> n.Total:

var query = 
from nf in contexto.NotasFiscais
where nf.Total > contexto.NotasFiscais.Average(n => n.Total),
select new
{
    Numero = nf.NotaFiscalId,
    Data = nf.DataNotaFiscalId,
    Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
    Valor = nf.Total

};

Observe o código acima, ele mostra dois tipos de consulta query, uma externa que engloba todo código e outra interna que resume-se a: contexto.NotasFiscais.Average(n -> n.Total). A query interna é classificada como subquery e essa é uma novidade deste curso! Até o momento não tínhamos nos deparado com isso! Uma dado importante é que as subqueries podem ser utilizadas em distintos locais da consulta e não apenas no where.

A leitura da consulta, entretanto, está um pouco dificíl, pois estamos sobrepondo query com subquery. Dessa maneira, para facilitar, podemos refatorar a consulta para que seja extraída da definição da subconsulta uma variável. Para fazer isso selecionamos o trecho que corresponde a subconsulta, o contexto.NotasFiscais.Average(n -> n.Total). Aplicamos nele a refatoração através do atalho "Ctrl + .." e escolhemos a opção disponível de Introduce local for 'contexto...':

Dessa forma, é criada uma variável chamada "V". Vamos renomeá-la para queryMedia e teremos o seguinte:

var queryMedia = contexto.NotasFiscais.Average(n => n.Total),

var query = 
from nf in contexto.NotasFiscais
where nf.Total > queryMedia
select new
{
    Numero = nf.NotaFiscalId,
    Data = nf.DataNotaFiscalId,
    Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
    Valor = nf.Total

};

Ao rodar o código o resultado são valores desordenados. Para organizá-los vamos adicionar o order by nf.Total e como queremos que os elementos sejam arrumados de maneira decrescente, adicionamos o descending. Temos o seguinte:

var query = 
from nf in contexto.NotasFiscais
where nf.Total > queryMedia
orderby nf.Total descending
select new
{
    Numero = nf.NotaFiscalId,
    Data = nf.DataNotaFiscalId,
    Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
    Valor = nf.Total
};

Com esta modificação no código podemos rodá-lo que os objetos serão ordenados de maneira decrescente!

A dúvida é: Estarão todas as notas ordenadas de maneira decrescente ou apenas aquelas acima da média?

Para verificar essa informação, inserimos, abaixo dos campos do Console, um comando que indica que a média das notas deve ser impressa. Assim, vamos introduzir o Console.WriteLine() e passamos para ele a "A média é {0}". Junto disso colocamos a variável que armazena as expressões, a queryMedia. O código final ficará da seguinte maneira:

var query = 
from nf in contexto.NotasFiscais
where nf.Total > queryMedia
orderby nf.Total descending
select new
{
    Numero = nf.NotaFiscalId,
    Data = nf.DataNotaFiscalId,
    Cliente = nf.Cliente.PrimeiroNome + " " + nf.Cliente.Sobrenome,
    Valor = nf.Total 
};

foreach (var notaFiscal in query)
{

 Console.WriteLine("{0}\t{1}\{2}\t{3}", 
    notaFiscal.Numero,
    notaFiscal.Data,
    notaFiscal.Cliente,
    notaFiscal.Valor);
}

Console.WriteLine("A média é {0}", queryMedia);

Console.ReadKey();

Rodando o código o resultado obtido é um relatório que mostra objetos superiores a média, são mostrados os itens acima de 5,65 até o maior valor de venda, o de 25,86:

Nesta aula aprendemos a utilizar uma subconsulta para deixar o código mais simples e fácil de manter! Caso quiséssemos modificar a consulta mãe teríamos que expandi-la, acrescentar cláusula, etc e isso dificultaria a consulta como um todo. Dessa maneira, aprendemos a separar em queries menores para facilitar nossa vida!

Sobre o curso Entity LinQ parte 2: Store Procedures e consultas com o LinQPad

O curso Entity LinQ parte 2: Store Procedures e consultas com o LinQPad possui 183 minutos de vídeos, em um total de 41 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda .NET acessando integralmente esse e outros cursos, comece hoje!

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana