/// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - e como usar Stored Procedures?
        ///         - motivação: chamar a SP que retorna o total de atores distintos que atuaram em filmes de uma categoria qualquer
        ///         - usar uma SP que passa parâmetros
        ///         - método DbContext.Database.ExecuteSqlCommand
        ///         - importância de definir corretamente os parâmetros
        ///           - new SqlParameter
        ///         - usar parâmetros de saída
        ///         - mostrar no console
        ///         - dizer que é possível também enviar comandos UPDATE, INSERT e DELETE
        ///         - e que o método retornar os registros afetados
        /// </summary>
        public static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                //habilitar o log depois de executar uma vez o LINQ!
                contexto.StartLogSqlToConsole();

                var categ     = "Games";
                var nomeCateg = new SqlParameter
                {
                    ParameterName = "category_name",
                    Size          = 25,
                    Value         = categ
                };
                var totalAtores = new SqlParameter
                {
                    ParameterName = "total_actors",
                    Size          = 4,
                    Direction     = System.Data.ParameterDirection.Output
                };

                contexto.Database
                .ExecuteSqlCommand(
                    "total_actors_from_given_category",
                    nomeCateg,
                    totalAtores);

                Console.WriteLine($"O total de atores distintos da categoria {categ} é {totalAtores.Value}.");
            }
        }
Beispiel #2
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - também é possível enviar comandos UPDATE, INSERT e DELETE
        ///         - por exemplo, queremos dar carga em alguns registros
        ///         - migration?
        ///         - e que o método retornar os registros afetados
        /// </summary>
        public static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                //habilitar o log depois de executar uma vez o LINQ!
                contexto.StartLogSqlToConsole();

                //var insertSql =
                //    @"INSERT INTO language (name) VALUES
                //    ('Portuguese'), ('Spanish'), ('Zulu');";

                //var registrosAfetados = contexto
                //    .Database
                //    .ExecuteSqlCommand(insertSql);

                //Console.WriteLine($"Foram afetados {registrosAfetados} registros na execução do último comando.");

                var updateSql =
                    @"UPDATE film SET 
                        release_year = 1994
                        WHERE film_id > 750 AND film_id < 830";

                var registrosAfetados = contexto
                                        .Database
                                        .ExecuteSqlCommand(updateSql);

                Console.WriteLine($"Foram afetados {registrosAfetados} registros na execução do último comando.");

                var filmesDe94 = contexto.Filmes.Where(f => f.AnoLancamento == "1994");

                Console.WriteLine($"Filmes de 94 são {filmesDe94.Count()}");
            }
        }
        /// <summary>
        ///     Pré-requisitos:
        ///         - bando de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - agora vamos relacionar atores a filmes
        ///         - sabemos que um ator pode estrelar vários filmes
        ///         - ...e um filme tem um elenco com vários atores
        ///         - relacionamento Muitos para Muitos
        ///         - no curso anterior vimos que o EF Core não suporta M para N sem uma classe de join
        ///         - vamos modelar isso em nossas classes
        ///         - criar classe FilmeAtor, com propriedades de navegação Filme e Ator
        ///         - e a chave primária? No banco ela é formada pela junção de actor_id e film_id
        ///         - criar classe de configuração com a definição da chave
        ///         - gerar o script e verificar se está ok
        ///         - observar que essa tabela não serve de nada, precisamos dos relacionamentos
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                var info = contexto.GetDBTableInfo(typeof(FilmeAtor));
                Console.WriteLine(info.NomeTabela);
            }
        }
 /// <summary>
 ///     Pré-requisitos:
 ///         - bando de dados AluraFilmes criado e populado
 ///         - EF Core instalado no projeto
 ///         - classe LogSQLExtensions criada para logar o SQL
 ///     Objetivos:
 ///         - configurar os nomes de tabelas e colunas usando Fluent API no método OnModelCreating
 ///         - executar e observar que o programa vai funcionar exatamente como antes!
 ///         - explicar que no processo de mapeamento, o terceiro passo é Verificar o método OnModelCreating
 /// </summary>
 static void Main()
 {
     using (var contexto = new AluraFilmesContexto())
     {
         contexto.StartLogSqlToConsole();
         foreach (var ator in contexto.Atores)
         {
             System.Console.WriteLine(ator);
         }
     }
 }
Beispiel #5
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - vamos mapear agora as tabelas staff e customer
        ///         - representam Funcionarios
        ///         - e Clientes
        ///         - vamos criar a classe Funcionario
        ///         - e configurar seu mapeamento
        ///         - atenção para os tipos de dados
        ///         - fazer um SELECT pra testar; show!
        ///         - agora vamos criar a classe Cliente
        ///         - peraí! as propriedades são muito parecidas!!
        ///         - poderiam fazer parte de uma herança
        ///         - como mapear no EF?
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                foreach (var func in contexto.Funcionarios)
                {
                    Console.WriteLine(func);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - bando de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - observar os valores do campo Rating.
        ///         - no banco existe uma restrição CHECK que valida os seguintes valores:
        ///             ADD CONSTRAINT [CHECK_special_rating] CHECK ([rating]='NC-17' OR [rating]='R' OR [rating]='PG-13' OR [rating]='PG' OR [rating]='G');
        ///             que significam (G) - Livre, (PG) - Menores10, (PG-13) - Menores13, (R) - Restrito, (NC-17)- Maiores18
        ///         - como podemos mapear no lado das classes? Enums!
        ///         - e qual a convenção para Enumerados no Entity?
        ///         - olhar o script para descobrir que vai mapear para um int
        ///         - criamos o enum, e criamos uma prop desse tipo
        ///         - mas dps q fazemos  a mudança pra enum, dá erro de conversão!
        ///         - como resolver?
        ///         - duas propriedades: uma do tipo string com private set
        ///         - e outra do tipo enum, mas com getter e setter explícito para converter a string em enum e vice versa
        ///         - além disso, informar ao EF que queremos ignorar a prop enum
        ///         - testar o SELECT novamente
        ///         -
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                foreach (var filme in contexto.Filmes)
                {
                    System.Console.WriteLine(filme);
                }

                //var f = new Filme();
                //f.ClassificacaoIndicativa = ClassificacaoIndicativa.Livre;
                //System.Console.WriteLine(f.Classificacao);
            }
        }
        /// <summary>
        ///     Pré-requisitos:
        ///         - bando de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - mostrar que a coluna last_update tem um valor padrão para data/hora atual quando inserida
        ///         - maiores detalhes em https://docs.microsoft.com/en-us/ef/core/modeling/relational/default-values
        ///         - explicar as convenções
        ///         - como mapear essa estratégia para a coluna last_update?
        ///         - só pode ser definida via Fluent API
        ///         - através do método HasDefaultValueSql("getdate()")
        ///
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                var atorQualquer = contexto.Atores.First();

                MostraDataAtualizacaoAtor(contexto, atorQualquer);

                atorQualquer.UltimoNome = "STALLONE";
                contexto.SaveChanges();

                MostraDataAtualizacaoAtor(contexto, atorQualquer);
            }
        }
Beispiel #8
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - como superar as limitações do EF?
        ///         - fazer um SELECT com join entre a view e a tabela da entidade
        ///         - dá pra usar LINQ depois do FromSql, por exemplo Include
        ///         - e daí conseguimos pegar o total de filmes
        ///         - usando o nosso SELECT ideal!
        ///         - mas esse SELECT não é bom ficar chapado na string
        ///         - podemos usar uma VIEW armazenada no banco de dados
        ///         - mas como usar no EF? É possível?
        /// </summary>
        public static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                //habilitar o log depois de executar uma vez o LINQ!
                contexto.StartLogSqlToConsole();

                //recuperando via LINQ
                //var atoresMaisAtuantesPorLinq = contexto.Atores
                //    .Include(a => a.Filmografia)
                //    .Select(a => new { PrimeiroNome = a.PrimeiroNome, TotalFilmes = a.Filmografia.Count })
                //    .ToList()
                //    .OrderByDescending(a => a.TotalFilmes)
                //    .Take(5);

                //atoresMaisAtuantesPorLinq
                //    .ToList()
                //    .ForEach(a => MostrarAtuacao(a.PrimeiroNome, a.TotalFilmes));

                //como executamos muitos SELECTs, optamos por chamar uma view...
                //var atoresMaisAtuantesPorSP = contexto.Atores
                //        .FromSql("select * from dbo.top5_most_starred_actors");
                //foreach (var ator in atoresMaisAtuantesPorSP)
                //{
                //    Console.WriteLine(ator);
                //}

                //mas o EF tem limitações quanto a chamar Views e SPs (ver acima)
                //então lidamos com essas limitações para retornar apenas os atores
                var selectSQL =
                    @"select a.*
                    from actor a
                      inner join (
                        select top 5 a.actor_id, count(fa.film_id) as total
                        from actor a inner join film_actor fa on fa.actor_id = a.actor_id
                        group by a.actor_id, a.first_name, a.last_name
                        order by total ) top5 on a.actor_id = top5.actor_id";

                var atoresMaisAtuantes = contexto.Atores
                                         .FromSql(selectSQL)
                                         .Include(a => a.Filmografia);

                atoresMaisAtuantes
                .ToList()
                .ForEach(a => MostrarAtuacao(a.PrimeiroNome, a.Filmografia.Count));
            }
        }
        /// <summary>
        /// Atualiza 20 filmes com idiomas originais randômicos.
        /// </summary>
        public static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                var filmes  = contexto.Filmes.Take(20);
                var idiomas = contexto.Idiomas.ToList();

                foreach (var filme in filmes)
                {
                    filme.IdiomaOriginal = idiomas.RandomItem();
                }

                contexto.SaveChanges();
            }
        }
Beispiel #10
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - mas esse SELECT não é bom ficar chapado na string
        ///         - podemos usar uma VIEW armazenada no banco de dados
        ///         - mas como usar no EF? É possível?
        ///         - mostrar docs da Microsoft dizendo que não é suportado
        ///         - que existe uma issue para implementar no futuro
        ///         - mas é possível usar do mesmo jeito que fizemos no vídeo anterior
        ///         - legal!
        ///         - e com Stored Procedures?
        /// </summary>
        public static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                //habilitar o log depois de executar uma vez o LINQ!
                contexto.StartLogSqlToConsole();

                //para usar views fazemos igualzinho ao vídeo anterior!
                var atoresMaisAtuantes = contexto.Atores
                                         .FromSql("select a.* from actor a inner join dbo.top5_most_starred_actors top5 on a.actor_id = top5.actor_id")
                                         .Include(a => a.Filmografia);

                atoresMaisAtuantes
                .ToList()
                .ForEach(a => MostrarAtuacao(a.PrimeiroNome, a.Filmografia.Count));
            }
        }
        /// <summary>
        ///     Pré-requisitos:
        ///         - bando de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - observar que essa tabela não serve de nada, precisamos dos relacionamentos
        ///         - queremos fazer contexto.Filmes.Include(f => f.Elenco).ThenInclude(e => e.Ator);
        ///         - introduzir os termos do EF para relações (PPT!):
        ///             - entidade Dependente (ex. FilmeAtor)
        ///             - entidade Principal (ex. Filme/Ator)
        ///             - Chave Estrangeira (ex. FilmeAtor.FilmeId/FilmeAtor.AtorId)
        ///             - Chave Principal (ex. Filme.Id/Ator.Id)
        ///             - Propriedade de Navegação:
        ///                 - Propriedade de Navegação do tipo Coleção (ex. Filme.Elenco/Ator.Filmografia)
        ///                 - Propriedade de Navegação do tipo Referência (ex. FilmeAtor.Filme/FilmeAtor.Ator)
        ///                 - Propriedade de Navegação Inversa (ex. Filme.Elenco = FilmeAtor.Filme / Ator.Filmografia = FilmeAtor.Ator)
        ///             - criar as propriedades de navegação de coleção nas entidades principais Filme e Ator
        ///             - testar o SELECT, dará o sgte erro:
        ///             Exceção Sem Tratamento: System.Data.SqlClient.SqlException:
        ///                 Invalid column name 'AtorId'.
        ///                 Invalid column name 'FilmeId'.
        ///             - mostrar as convenções do EF, e observar que do jeito que fizemos
        ///                 o EF está procurando pelas colunas FilmeId e AtorId
        ///             - repare no SELECT gerado pelo join
        ///             SELECT [f0].[film_id], [f0].[actor_id], [f0].[AtorId], [f0].[FilmeId], [a].[actor_id], [a].[first_name], [a].[last_name], [a].[last_update]
        ///             FROM[film_actor] AS[f0]
        ///             INNER JOIN(
        ///                 SELECT DISTINCT TOP(1) [f].[film_id]
        ///                 FROM[film] AS[f]
        ///                 ORDER BY[f].[film_id]
        ///             ) AS[f1] ON[f0].[FilmeId] = [f1].[film_id]
        ///             LEFT JOIN[actor] AS[a] ON[f0].[AtorId] = [a].[actor_id]
        ///             ORDER BY[f1].[film_id]
        ///             - configurar as chaves estrangeiras:
        ///                 - entityBuilder.HasOne(fa => fa.Filme).WithMany(f => f.Elenco).HasForeignKey("film_id");
        ///                 - entityBuilder.HasOne(fa => fa.Ator).WithMany(a => a.Filmografia).HasForeignKey("actor_id");
        ///             - testar o SELECT; vai funfar!
        ///             - testar o script DDL
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                var filme = contexto.Filmes
                            .Include(f => f.Elenco)
                            .ThenInclude(e => e.Ator)
                            .First();

                Console.WriteLine($"Mostrando o elenco de {filme.Titulo}:");
                foreach (var item in filme.Elenco)
                {
                    Console.WriteLine(item.Ator);
                }
            }
        }
Beispiel #12
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - como mapear herança no EF?
        ///         - convenções de herança: TPH
        ///         - EF Core não implementa TPC, mas não precisamos pq vamos colocar no contexto apenas Funcionario e Cliente
        ///         - criar a classe abstrata pai: Pessoa
        ///         - propriedades Id, PrimeiroNome, UltimoNome, Email e Ativo
        ///         - herdar Funcionario de Pessoa
        ///         - testar o SELECT; deve funfar
        ///         - criar a classe Cliente
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                Console.WriteLine("Listando os funcionários..");
                foreach (var func in contexto.Funcionarios)
                {
                    Console.WriteLine(func);
                }

                Console.WriteLine("Listando os clientes...");
                foreach (var cliente in contexto.Clientes.Take(10))
                {
                    Console.WriteLine(cliente);
                }
            }
        }
Beispiel #13
0
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - motivação para fazer SQL puro:
        ///           - performance
        ///           - a query não pode ser expressa via LINQ
        ///           - insatisfação com o modo como EF gerou o SQL
        ///         - motivação: pegar os 5 atores que mais atuaram em filmes
        ///         - fazer via LINQ >> funciona!
        ///         - porém, mostrar o SQL com StartLog...
        ///         - não satisfatório
        ///         - mostrar o SELECT ideal numa janela de consulta SQL Server
        ///         - como faço para usar esse SELECT ideal?
        ///         - usar o FromSQL
        ///         - executando direto sem preocupar-se com as limitações, erro:
        ///         System.InvalidOperationException: The required column 'last_update' was not present in the results of a 'FromSql' operation.
        ///         - será que não conseguimos usar views ou stored procedures?
        ///         - mostrar as limitações no documento da MS
        ///         - limitações que devem ser consideradas quando usar SQL puro:
        ///           - as queries só podem retornar tipos que fazem parte do modelo
        ///           - as queries devem obrigatoriamente retornar dados para TODAS as propriedades
        ///           - nomes das colunas na query deve ser iguais as colunas mapeadas pelas propriedades
        ///           - a query não pode conter dados relacionados
        ///         - aplicar as limitações
        ///         -
        /// </summary>
        public static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                //habilitar o log depois de executar uma vez o LINQ!
                contexto.StartLogSqlToConsole();

                //recuperando via LINQ
                var atoresMaisAtuantesPorLinq = contexto.Atores
                                                .Include(a => a.Filmografia)
                                                .Select(a => new { PrimeiroNome = a.PrimeiroNome, TotalFilmes = a.Filmografia.Count })
                                                .ToList()
                                                .OrderByDescending(a => a.TotalFilmes)
                                                .Take(5);

                atoresMaisAtuantesPorLinq
                .ToList()
                .ForEach(a => MostrarAtuacao(a.PrimeiroNome, a.TotalFilmes));
            }
        }
Beispiel #14
0
 static void Main()
 {
     using (var contexto = new AluraFilmesContexto())
     {
         contexto.StartLogSqlToConsole();
         var frances = contexto.Idiomas.Where(i => i.Nome == "French").First();
         if (frances != null)
         {
             var primeirosDezFilmes = contexto.Filmes.Take(10).ToList();
             primeirosDezFilmes.ForEach(f => f.IdiomaFalado = frances);
             contexto.SaveChanges();
         }
         else
         {
             Console.WriteLine("Não tinha um idioma com esse nome...");
             foreach (var idioma in contexto.Idiomas)
             {
                 Console.WriteLine(idioma);
             }
         }
     }
 }
        /// <summary>
        ///     Pré-requisitos:
        ///         - banco de dados AluraFilmes criado e populado
        ///         - EF Core instalado no projeto
        ///         - classe LogSQLExtensions criada para logar o SQL
        ///     Objetivos:
        ///         - vamos mapear agora a relação Filme x Idioma
        ///         - repare que um filme tem dois idiomas: um original (que pode ser nulo), outro que indica o idioma da mídia em estoque (não nulo)
        ///         - neste caso, como fazer? neste caso não podemos contar com as convenções
        ///         - primeiro vamos criar a classe Idioma e configurar seu mapeamento
        ///         - fazer um SELECT pra testar
        ///         - erro no tipo language_id: mudar prop pra byte
        ///         - funfou
        ///         - agora mapear os 2 relacionamentos 1 x N - TESTAR SE VAI FUNFAR SEM CONFIGURAR
        ///         - 1o) relação IdiomaFalado; relembrar termos...
        ///             - Entidade Principal: Idioma
        ///             - Entidade Dependente: Filme
        ///             - Chave Estrangeira: shadow property Filme.language_id
        ///             - Chave Principal: Idioma.Id
        ///             - Navegação Coleção: Idioma.FilmesFalados
        ///             - Navegação Referência: Filme.IdiomaFalado
        ///             - criar relação
        ///             - lembrar que essa relação é NOT NULL (script tem que acusar...)
        ///         - 2o) relação IdiomaOriginal; relembrar termos:
        ///             - Entidade Principal: Idioma
        ///             - Entidade Dependente: Filme
        ///             - Chave Estrangeira: shadow property Filme.original_language_id
        ///             - Chave Principal: Idioma.Id
        ///             - Navegação Coleção: Idioma.FilmesOriginais
        ///             - Navegação Referência: Filme.IdiomaOriginal
        ///             - criar relação
        ///             - lembrar que essa relação pode ser NULL (script tem que acusar...)
        ///             - ou seja, colocar Property<byte?> na shadow property
        ///          - fazer um SELECT em filmes com idioma falado == "French"
        ///          - necessário rodar um script de carga
        /// </summary>
        static void Main()
        {
            using (var contexto = new AluraFilmesContexto())
            {
                contexto.StartLogSqlToConsole();

                foreach (var idioma in contexto.Idiomas)
                {
                    Console.WriteLine(idioma);
                }

                var idiomaPesquisado = "French";
                Console.WriteLine($"\nFilmes cujo idioma falado é {idiomaPesquisado}:");
                var filmesNoIdiomaPesquisado = contexto.Filmes
                                               .Include(f => f.IdiomaFalado)
                                               .Include(f => f.IdiomaOriginal)
                                               .Where(f => f.IdiomaFalado.Nome == idiomaPesquisado);

                foreach (var filme in filmesNoIdiomaPesquisado)
                {
                    Console.WriteLine(filme);
                }
            }
        }