private static void ListaUltimo10AtoresCadastrados() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); //Modificando a shadowProperty //var ator = new Ator(); //ator.PrimeiroNome = "Tom"; //ator.UltimoNome = "Hanks"; //contexto.Entry(ator).Property("last_update").CurrentValue = DateTime.Now; //contexto.Add(ator); ///Utilizando a shadow property em query ///O EF está dentro do using Microsoft.EntityFrameworkCore; var atores = contexto.Atores .OrderByDescending(x => EF.Property <DateTime>(x, "last_update")) .Take(10); foreach (var item in atores) { Console.WriteLine(item + " - " + contexto.Entry(item).Property("last_update").CurrentValue); } //contexto.SaveChanges(); } }
private static void FilmeClassificacao() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); //var livre = ClassificacaoIndicativa.Livre; //Console.WriteLine(livre.ParaString()); //var maior = ClassificacaoIndicativa.MaiorQue18; //Console.WriteLine(maior.ParaString()); //Console.WriteLine("G".ParaValor()); var filme = new Filme(); filme.Titulo = "Senhor dos Anéis"; filme.Duracao = 120; filme.AnoLancamento = "2000"; filme.Classificacao = ClassificacaoIndicativa.MaiorQue14; filme.IdiomaFalado = contexto.Idiomas.First(); contexto.Filmes.Add(filme); contexto.SaveChanges(); var filmeInserido = contexto.Filmes.First(f => f.Titulo == "Senhor dos Anéis"); Console.WriteLine(filmeInserido.Classificacao); } }
private static void ConfigurandoRestricoesUnique() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var ator1 = new Ator { PrimeiroNome = "Emma", UltimoNome = "Watson" }; var ator2 = new Ator { PrimeiroNome = "Emma", UltimoNome = "Watson" }; contexto.Atores.AddRange(ator1, ator2); contexto.SaveChanges(); var emmaWatson = contexto.Atores .Where(a => a.PrimeiroNome == "Emma" && a.UltimoNome == "Watson"); Console.WriteLine($"Total de atores encontrados: {emmaWatson.Count()}"); } Console.ReadLine(); }
/// <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}."); } }
private static void FromSqlESuasLimitacoes() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var sql = @"select a.* from actor a inner join (select top 5 a.actor_id, count(*) as total from actor a inner join film_actor fa on fa.actor_id = a.actor_id group by a.actor_id order by total desc) filmes on filmes.actor_id = a.actor_id"; var atoresMaisAtuantes = contexto.Atores .FromSql(sql) .Include(a => a.Filmografia); foreach (var ator in atoresMaisAtuantes) { Console.WriteLine($"O ator {ator.PrimeiroNome} {ator.UltimoNome} atuou em {ator.Filmografia.Count} filmes."); } } Console.ReadLine(); }
private static void UsandoStoredProcedures() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var categoria = "Action"; // 36 var paramCategoria = new SqlParameter("category_name", categoria); var paramTotal = new SqlParameter { ParameterName = "@total_actors", Size = 4, Direction = ParameterDirection.Output }; contexto.Database .ExecuteSqlCommand( "execute total_actors_from_given_category @category_name, @total_actors OUT", paramCategoria, paramTotal ); Console.WriteLine($"O total de atores na categoria {categoria} é de {paramTotal.Value}."); } Console.ReadLine(); }
private static void ModeloDeDadosDoEntity() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var filme = new Filme { Titulo = "Casino Royale", Duracao = 120, AnoLancamento = "2000", Classificacao = ClassificacaoIndicativa.MaioresQue14, IdiomaFalado = contexto.Idiomas.First() }; contexto.Entry(filme).Property("last_update").CurrentValue = DateTime.Now; contexto.Filmes.Add(filme); contexto.SaveChanges(); var filmeInserido = contexto.Filmes.First(f => f.Titulo == "Casino Royale"); Console.WriteLine(filmeInserido.Classificacao); } Console.ReadLine(); }
private static void AssumindoAsRedeasDoSQLGerado() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); //var atoresMaisAtuantes = contexto.Atores // .Include(a => a.Filmografia) // .OrderByDescending(a => a.Filmografia.Count) // .Take(5); var sql = @"select top 5 a.first_name, a.last_name, count(*) as total from actor a inner join film_actor fa on fa.actor_id = a.actor_id group by a.first_name, a.last_name order by total desc"; var atoresMaisAtuantes = contexto.Atores.FromSql(sql); foreach (var ator in atoresMaisAtuantes) { Console.WriteLine($"O ator {ator.PrimeiroNome} {ator.UltimoNome} atuou em {ator.Filmografia.Count} filmes."); } } Console.ReadLine(); }
/// <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()}"); } }
static void Main(string[] args) { using (var contexto = new AluraFilmesContexto()) { foreach (var ator in contexto.Atores) { System.Console.WriteLine(ator); } } }
/// <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); } }
private static void ConsultasUsandoComandoSQL() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); /* USANDO CONSULTA LINQ POR MÉTODO */ //var atores = contexto.Atores // .Include(a => a.Filmografia) // .OrderByDescending(a => a.Filmografia.Count) // .Take(5); /* USANDO FROMSQL */ //var sql = @"SELECT a.* // FROM dbo.actor a // INNER JOIN ( SELECT TOP 5 a.actor_id, COUNT(*) AS total // FROM dbo.actor a // INNER JOIN dbo.film_actor fa ON fa.actor_id = a.actor_id // GROUP BY a.actor_id // ORDER BY total DESC ) filmes ON filmes.actor_id = a.actor_id"; //var atores = contexto.Atores // .FromSql(sql) // .Include(a => a.Filmografia); /* USANDO FROMSQL */ var sql = @"SELECT a.* FROM dbo.actor a INNER JOIN top5_most_starred_actors filmes ON filmes.actor_id = a.actor_id"; var atores = contexto.Atores .FromSql(sql) .Include(a => a.Filmografia); foreach (var ator in atores) { Console.WriteLine($"O {ator.PrimeiroNome} {ator.UltimoNome} atuou em {ator.Filmografia.Count} filmes"); } /* EXEMPLO COM CONSULTA LINQ */ //var atores = from f in contexto.Atores // let Total = f.Filmografia.Count // orderby Total descending // select new // { // Nome = f.PrimeiroNome + " " + f.UltimoNome, // Total // }; //atores = atores.Take(5); //foreach (var ator in atores) //{ // Console.WriteLine("{0}, {1}", ator.Nome, ator.Total); //} } }
/// <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); } } }
private static void RecuperandoValoresDaPropriedadeShadowProperty() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var ator = contexto.Atores.First(); Console.WriteLine(ator + " " + contexto.Entry(ator).Property("last_update").CurrentValue); } }
private static void ListarFilmes() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); foreach (var filme in contexto.Filmes) { Console.WriteLine(filme); } } }
static void Main(string[] args) { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); foreach (var idioma in contexto.Idiomas) { Console.WriteLine(idioma); } } }
private static void ExibeAsCategorias() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); foreach (var item in contexto.Categorias) { Console.WriteLine(item); } } }
private static void ConvertendoEnumParaValor() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var livre = ClassificacaoIndicativa.MaioresQue13; Console.WriteLine(livre.ParaString()); Console.WriteLine(livre.ParaString().ParaValor()); } }
/// <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); } } }
private static void UtilizandoSQLManualParaSubustituirOEntity() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); //Usando SQL injetado na mão //Ele tem uma limitação, que dessa forma só pode voltar dados de uma coluna e deve conter todas as colunas //da entidade //var sql = @" // select a.* // from actor a // join ( // select top 5 a.actor_id, count(a.actor_id) total // from actor a // join film_actor fa on a.actor_id = fa.actor_id // group by a.actor_id, a.first_name, a.last_name // order by total desc // ) filmes on filmes.actor_id = a.actor_id"; //var atoresMaisAtuantes = contexto // .Atores // .FromSql(sql) // .Include(x=> x.Filmografia) // .OrderByDescending(x=> x.Filmografia.Count); //Utilizando a view top5_most_starred_actors var sql = @" select a.* from actor a join top5_most_starred_actors filmes on filmes.actor_id = a.actor_id"; var atoresMaisAtuantes = contexto .Atores .FromSql(sql) .Include(x => x.Filmografia) .OrderByDescending(x => x.Filmografia.Count); //Usando EF para fazer a query //var atoresMaisAtuantes = contexto // .Atores // .Include(x=> x.Filmografia) // .OrderByDescending(x=> x.Filmografia.Count) // .Take(5); foreach (var ator in atoresMaisAtuantes) { Console.WriteLine($"O ator {ator.PrimeiroNome} {ator.UltimoNome} atuou em {ator.Filmografia.Count} filmes"); } } }
/// <summary> /// Pré-requisitos: /// - bando de dados AluraFilmes criado e populado /// - EF Core instalado no projeto /// - classe LogSQLExtensions criada para logar o SQL /// Objetivos: /// - recuperar o valor da shadow property last_update /// - através do método EF.Property<DateTime>(a, "last_update") na query /// /// </summary> static void Main() { using (var contexto = new AluraFilmesContexto()) { var atores = contexto.Atores .OrderByDescending(a => EF.Property <DateTime>(a, "last_update")) .Select(a => new { Nome = a.PrimeiroNome + " " + a.UltimoNome, UltimaAtualizacao = EF.Property <DateTime>(a, "last_update") }); foreach (var ator in atores) { System.Console.WriteLine($"{ator.Nome} - {ator.UltimaAtualizacao:dd/MM/yyyy}"); } } }
private static void MultiplosRelacionamentosMesmasTabelas() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); foreach (var idioma in contexto.Idiomas) { Console.WriteLine(idioma); } } Console.ReadLine(); }
/// <summary> /// Pré-requisitos: /// - bando de dados AluraFilmes criado e populado /// - EF Core instalado no projeto /// - classe LogSQLExtensions criada para logar o SQL /// Objetivos: /// - configurar a nulidade de uma coluna /// - tanto via anotação, através do atributo Required /// - quanto via Fluent API, através do método IsRequired /// - gerar o script novamente, e verificar que agora está melhor /// - porém, ainda temos que resolver como tratar a coluna last_update /// - é possível ter uma coluna no banco sem estar mapeada na classe? /// </summary> static void Main() { using (var contexto = new AluraFilmesContexto()) { var info = contexto.GetDBTableInfo(typeof(Ator)); System.Console.WriteLine("Informações de Mapeamento..."); System.Console.WriteLine($"Classe: {info.NomeClasse} >> Tabela: {info.NomeTabela}"); foreach (var col in info.Columns) { System.Console.WriteLine($"Propriedade: {col.NomePropriedade} >> Coluna: {col.NomeColuna} - tipo: {col.TipoColuna}, tamanho: {col.TamanhoColuna}, pode ser nulo? {col.EhNulo}"); } } }
public static void ImprimeFilmes() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var atores = contexto.Filmes; foreach (var filme in atores) { Console.WriteLine(filme); } } }
private static void ExecutarInsertDelete() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var sql = "INSERT INTO dbo.language (name) VALUES ('Teste 1'), ('Teste 2'), ('Teste 3')"; var registrosAfetados = contexto.Database.ExecuteSqlCommand(sql); Console.WriteLine($"Total de registros afetados: {registrosAfetados}"); sql = "DELETE FROM dbo.language WHERE name LIKE ('Teste%')"; registrosAfetados = contexto.Database.ExecuteSqlCommand(sql); Console.WriteLine($"Total de registros afetados: {registrosAfetados}"); } }
private static void Lista10AtoresModificadosRecentemente() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var atores = contexto.Atores .OrderByDescending(a => EF.Property <DateTime>(a, "last_update")) .Take(10); foreach (var ator in atores) { Console.WriteLine("{0} - {1}", ator, contexto.Entry(ator).Property("last_update").CurrentValue); } } }
/// <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); } }
public static void ImprimeAtores() { using (var contexto = new AluraFilmesContexto()) { contexto.LogSQLToConsole(); var atores = contexto.Atores .OrderBy(a => EF.Property <DateTime>(a, "last_update")) .Take(10); foreach (var ator in atores) { Console.WriteLine(ator + " - " + contexto.Entry(ator).Property("last_update").CurrentValue); } } }
/// <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: /// - 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)); } }