Curso Entity Framework - Consultas Projeção - XI
Nesta aula vamos abordar as consultas projeção no Entity Framework.(aula anterior) |
Nesta aula iremos abordar o LINQ-to-Entities e o recurso Projeção (Projection). Para acompanhar a aula você deve ter um conhecimento básico de LINQ.
A LINQ - Language integrated Query - é um conjunto de recursos introduzidos no .NET Framework 3.5 que permitem a realização de consultas diretamente em base de dados , documentos XML , estrutura de dados , coleção de objetos ,etc. usando uma sintaxe parecida com a linguagem SQL.
Ao usar
aplicativos executados localmente, em alguns cenários, você pode revisar as
consultas para refinar ainda mais a quantidade de dados retornada do banco de
dados. Uma técnica a ser considerada é o uso de projeções, que permite a você
muito mais controle sobre quais dados relacionados são retornados.
Nem o Eager Loading(carregamento imediato), nem o
Lazy Loading(carregamento deferido/lento) no Entity
Framework permitem que você filtre ou classifique os dados relacionados que
estão sendo retornados. Porém, em uma projeção, você pode fazer isso. (
http://msdn.microsoft.com/pt-br/magazine/gg309181.aspx )
A projeção é um processo de seleção de dados em um formato diferente, em vez de consultar uma entidade específica. Há muitas maneiras de projeção. Vamos ver agora alguns estilos de projeção:
recursos usados :
Preparando o ambiente
Crie uma novo solução no VS 2013 Express for Windows desktop com o nome EF6_EscolaDB
No menu File clique em Add -> New Project e inclua um projeto do tipo Class Library com o mesmo nome da solução;
A seguir inclua um Entity Data Model no menu PROJET -> Add New Item selecionando o template ADO .NET Entity Data Model e informando o nome EscolaDB.edmx selecionando todas as tabelas do banco de dados EscolaDB.mdf.
Nota: O ambiente e o banco de dados EscolaDB.mdf forma definidos nas aulas 1 , 2 e 3.
Dessa forma teremos criado um contexto chamado EscolaDBEntities que iremos usar para acessar as entidades e realizar as consultas.
Após isso inclua um novo projeto do tipo Console Application com o nome Consultas_Projecao na solução;
Para concluir inclua uma referência ao projeto Consultas_Projecao para o projeto EF6_EscolaDB, inclua a string de conexão no arquivo App.Config do projeto template e inclua uma referência ao Entity Framework no projeto.
1- First ou FirstOrDefault
Se você deseja obter um único objeto, como um aluno por exemplo, quando existem muitos alunos com o mesmo nome no banco de dados, você pode usar First ou FirstOrDefault:
Exemplo:
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var aluno = (from a in ctx.Alunos
where a.AlunoNome == "Janice"
select a).FirstOrDefault<Aluno>();
Console.WriteLine(aluno.AlunoNome.ToString());
Console.ReadKey();
}
|
SELECT TOP (1)
[Extent1].[AlunoId] AS [AlunoId],
[Extent1].[AlunoNome] AS [AlunoNome],
[Extent1].[PadraoId] AS [PadraoId]
FROM [dbo].[Aluno] AS [Extent1]
WHERE N'Janice' = [Extent1].[AlunoNome]
|
A consulta localiza um aluno cujo nome seja igual a 'Janice'. Com FirstOrDefault() será localizada a primeira ocorrência.
A diferença entre First e FIrstOrDefault é que First() irá lançar uma exceção se não existir dados para o critério informado ao passo que FirstOrDefault retorna o valor padrão (null) se não existir dados.
2- Single ou SingleOrDefault
Podemos usar também Single ou SingleOrDefault para obter um único objeto, por exemplo aluno com o nome igual a 'Janice', quando não existirem mais de um objeto:
Exemplo:
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var aluno = (from a in ctx.Alunos
where a.AlunoNome == "Janice"
select a).SingleOrDefault<Aluno>();
Console.WriteLine(aluno.AlunoNome.ToString());
Console.ReadKey();
}
|
SELECT TOP (2)
[Extent1].[AlunoId] AS [AlunoId],
[Extent1].[AlunoNome] AS [AlunoNome],
[Extent1].[PadraoId] AS [PadraoId]
FROM [dbo].[Aluno] AS [Extent1]
WHERE N'Janice' = [Extent1].[AlunoNome]
|
Tanto SingleOrDefault como Single irão lançar uma exceção, se o resultado contiver mais de um elemento. Use Single ou SingleOrDefault onde você tem certeza que o resultado irá conter apenas um elemento. Se o resultado tem vários elementos, então deve haver algum problema.
3 - ToListSe você deseja listar todos os alunos cujo nome é 'Janice' então use ToList():
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var aluno = (from a in ctx.Alunos
where a.AlunoNome == "Janice"
select a).ToList<Aluno>();
Console.ReadKey();
}
|
SELECT
[Extent1].[AlunoId] AS [AlunoId],
[Extent1].[AlunoNome] AS [AlunoNome],
[Extent1].[PadraoId] AS [PadraoId]
FROM [dbo].[Aluno] AS [Extent1]
WHERE N'Janice' = [Extent1].[AlunoNome]
|
4 - Group By
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var aluno = from a in ctx.Alunos
group a by a.AlunoId into AlunoGrupoId
select AlunoGrupoId;
Console.WriteLine(aluno);
Console.ReadKey();
}
|
|
5 - OrderBy
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var aluno = from a in ctx.Alunos orderby a.AlunoNome ascending select a; ; Console.ReadKey();
}
|
|
Usando classes anônimas para filtrar informações
Podemos usar o recurso das classes anônimas para criar projeções selecionando dados.
Os tipos anônimos fornecem uma maneira conveniente para encapsular um conjunto de propriedades somente leitura em um único objeto sem precisar primeiro definir explicitamente um tipo.
O nome do tipo é gerado pelo compilador e não está disponível no nível do código fonte. O tipo das propriedades é inferido pelo compilador.
Exemplo:
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var resultado = from a in ctx.Alunos where a.AlunoNome == "Macoratti" select new { a.AlunoId, a.AlunoEndereco, a.Cursos }; Console.ReadKey();
}
|
|
Na consulta acima usamos uma classe anônima (Select New) para selecionar o Id, Endereço e os cursos do aluno com nome igual a 'Macoratti'.
O tipo anônimo possui 3 propriedades : AlunoId, AlunoEndereco e Cursos.
Executando consultas aninhadas
Quando você escreve uma consulta, em qualquer lugar em um valor que é esperado você pode usar outra consulta em seu lugar, desde que essa consulta retorne um tipo aceitável. Você pode usar uma consulta aninhada no lugar de uma expressão ou uma coleção.
Exemplo:
using(var ctx = new EscolaDBEntities())
{
//Exibe o SQL gerado na janela Debug
ctx.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
var consulta = from a in ctx.Alunos from c in a.Cursos where a.PadraoId == 1 select new { a.AlunoNome, c }; var resultado = consulta.ToList(); Console.WriteLine(resultado); Console.ReadKey();
}
|
SELECT
[Extent1].[AlunoId] AS [AlunoId],
[Extent1].[AlunoNome] AS [AlunoNome],
[Join1].[CursoId1] AS [CursoId],
[Join1].[CursoNome] AS [CursoNome],
[Join1].[CursoLocalizacao] AS [CursoLocalizacao],
[Join1].[ProfessorId] AS [ProfessorId]
FROM [dbo].[Aluno] AS [Extent1]
INNER JOIN (SELECT [Extent2].[AlunoId] AS [AlunoId], [Extent3].[CursoId] AS [CursoId1], [Extent3].[CursoNome] AS [CursoNome],
[Extent3].[CursoLocalizacao] AS [CursoLocalizacao], [Extent3].[ProfessorId] AS [ProfessorId]
FROM [dbo].[AlunoCurso] AS [Extent2]
INNER JOIN [dbo].[Curso] AS [Extent3] ON [Extent3].[CursoId] = [Extent2].[CursoId] ) AS [Join1] ON [Extent1].[AlunoId] = [Join1].[AlunoId]
WHERE 1 = [Extent1].[PadraoId]
|
Neste exemplo estamos realizando duas consultas aninhadas consultando Alunos e Cursos. O resultado será uma lista anônima com objetos Alunos e Cursos.
Vimos assim algumas projeções mais básicas e usadas com LINQ.
Na próxima aula vamos tratar do Eager Loading no Entity Framework.
Rogo-vos, pois, eu, o preso do Senhor,
que andeis como é digno da vocação com que fostes chamados,
Com toda a humildade e mansidão, com longanimidade, suportando-vos uns aos
outros em amor,
Procurando guardar a unidade do Espírito pelo vínculo da paz.
Efésios 4:1-3
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências: