Entity Framework - Consultas de projeção
LINQ to Entities
Um dos conceitos mais importantes para entender o LINQ to Entities é que ele é uma linguagem declarativa. O foco está em definir quais informações você precisa, ao invés de em como obter as informações.
Isso significa que você pode gastar mais tempo trabalhando com dados e menos tempo tentando descobrir o código subjacente necessário para realizar tarefas como acessar o banco de dados.
É importante entender que as linguagens declarativas não removem nenhum controle do desenvolvedor, mas ajudam o desenvolvedor a concentrar a atenção no que é importante.
LINQ to Entities Essential Keywords
É importante conhecer as palavras-chave básicas usadas para criar uma consulta LINQ. Existem apenas algumas palavras-chave a serem lembradas, mas você pode combiná-las de várias maneiras para obter resultados específicos. A lista a seguir contém essas palavras-chave básicas e fornece uma descrição simples de cada uma.
Sr. Não. | Palavra-chave e descrição |
---|---|
1 | Ascending Especifica que uma operação de classificação ocorre do menor (ou menor) elemento de um intervalo para o elemento mais alto de um intervalo. Normalmente, esta é a configuração padrão. Por exemplo, ao realizar uma classificação alfabética, a classificação estaria no intervalo de A a Z. |
2 | By Especifica o campo ou expressão usado para implementar um agrupamento. O campo ou expressão define uma chave usada para realizar a tarefa de agrupamento. |
3 | Descending Especifica que uma operação de classificação ocorre do maior (ou mais alto) elemento de um intervalo para o elemento mais baixo de um intervalo. Por exemplo, ao realizar uma classificação alfabética, a classificação estaria no intervalo de Z a A. |
4 | Equals Usado entre as cláusulas esquerda e direita de uma instrução de junção para juntar a fonte de dados contextuais primária à fonte de dados contextuais secundária. O campo ou expressão à esquerda da palavra-chave equals especifica a fonte de dados primária, enquanto o campo ou expressão à direita da palavra-chave equals especifica a fonte de dados secundária. |
5 | From Especifica a fonte de dados usada para obter as informações necessárias e define uma variável de intervalo. Esta variável tem o mesmo propósito que uma variável usada para iteração em um loop. |
6 | Group Organiza a saída em grupos usando o valor-chave que você especificar. Use várias cláusulas de grupo para criar vários níveis de organização de saída. A ordem das cláusulas de grupo determina a profundidade em que um determinado valor-chave aparece na ordem de agrupamento. Você combina esta palavra-chave com por para criar um contexto específico. |
7 | In Usado de várias maneiras. Nesse caso, a palavra-chave determina a fonte de banco de dados contextual usada para uma consulta. Ao trabalhar com uma junção, a palavra-chave in é usada para cada fonte de banco de dados contextual usada para a junção. |
8 | Into Especifica um identificador que você pode usar como referência para cláusulas de consulta LINQ, como junção, grupo e seleção. |
9 | Join Cria uma única fonte de dados a partir de duas fontes de dados relacionadas, como em uma configuração mestre / detalhada. Uma junção pode especificar uma junção interna, de grupo ou externa esquerda, com a junção interna como padrão. Você pode ler mais sobre junções em msdn.microsoft.com |
10 | Let Define uma variável de intervalo que você pode usar para armazenar resultados de subexpressão em uma expressão de consulta. Normalmente, a variável de intervalo é usada para fornecer uma saída enumerada adicional ou para aumentar a eficiência de uma consulta (de forma que uma tarefa específica, como encontrar o valor em minúsculas de uma string, não precise ser feita mais de uma vez). |
11 | On Especifica o campo ou expressão usado para implementar uma junção. O campo ou expressão define um elemento que é comum a ambas as fontes de dados contextuais. |
12 | Orderby Cria uma ordem de classificação para a consulta. Você pode adicionar a palavra-chave crescente ou decrescente para controlar a ordem da classificação. Use várias cláusulas orderby para criar vários níveis de classificação. A ordem das cláusulas orderby determina a ordem em que as expressões de classificação são tratadas, portanto, usar uma ordem diferente resultará em uma saída diferente. |
13 | Where Define o que LINQ deve recuperar da fonte de dados. Você usa uma ou mais expressões booleanas para definir as especificações do que recuperar. As expressões booleanas são separadas umas das outras usando o && (AND) e || Operadores (OR). |
14 | Select Determina a saída da consulta LINQ especificando quais informações retornar. Essa instrução define o tipo de dados dos elementos que LINQ retorna durante o processo de iteração. |
Projeção
As consultas de projeção melhoram a eficiência de seu aplicativo, recuperando apenas campos específicos de seu banco de dados.
Depois de ter os dados, você pode querer projetá-los ou filtrá-los conforme necessário para moldar os dados antes da saída.
A principal tarefa de qualquer expressão LINQ to Entities é obter dados e fornecê-los como saída.
A seção “Desenvolvimento de consultas LINQ to Entities” deste capítulo demonstra as técnicas para realizar essa tarefa básica.
Vamos dar uma olhada no código a seguir, no qual a lista de alunos será recuperada.
using (var context = new UniContextEntities()) {
var studentList = from s in context.Students select s;
foreach (var student in studentList) {
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}
}
Objeto Único
Para recuperar um único objeto de aluno, você pode usar os métodos enumeráveis First () ou FirstOrDefault, que retornam o primeiro elemento de uma sequência. A diferença entre First e FirstOrDefault é que First () lançará uma exceção, se não houver dados de resultado para os critérios fornecidos, enquanto FirstOrDefault () retorna o valor padrão null, se não houver dados de resultado. No trecho de código abaixo, o primeiro aluno da lista será recuperado, cujo primeiro nome é Ali.
using (var context = new UniContextEntities()) {
var student = (from s in context.Students where s.FirstMidName
== "Ali" select s).FirstOrDefault<Student>();
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}
Você também pode usar Single () ou SingleOrDefault para obter um único objeto de aluno que retorna um único elemento específico de uma sequência. No exemplo a seguir, um único aluno é recuperado cujo ID é 2.
using (var context = new UniContextEntities()) {
var student = (from s in context.Students where s.ID
== 2 select s).SingleOrDefault<Student>();
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
Console.ReadKey();
}
Lista de Objetos
Se você deseja recuperar a lista de alunos cujo primeiro nome é Ali, você pode usar o método enumerável ToList ().
using (var context = new UniContextEntities()) {
var studentList = (from s in context.Students where s.FirstMidName
== "Ali" select s).ToList();
foreach (var student in studentList) {
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}
Console.ReadKey();
}
Ordem
Para recuperar dados / lista em qualquer ordem particular, você pode usar a palavra-chave orderby. No código a seguir, a lista de snippet do aluno será recuperada em ordem crescente.
using (var context = new UniContextEntities()) {
var studentList = (from s in context.Students orderby
s.FirstMidName ascending select s).ToList();
foreach (var student in studentList) {
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}
Console.ReadKey();
}
Consulta de estrutura de entidade de projeção Vs padrão
Suponhamos que você tenha um modelo de aluno que contém ID, FirstMidName, LastName e EnrollmentDate. Se você quiser retornar uma lista de Alunos, uma consulta padrão retornará todos os campos. Mas se você deseja obter apenas uma lista de alunos que contenham os campos ID, FirstMidName e LastName. É aqui que você deve usar uma consulta de projeção. A seguir está o exemplo simples de consulta de projeção.
using (var context = new UniContextEntities()) {
var studentList = from s in context.Students
orderby s.FirstMidName ascending
where s.FirstMidName == "Ali"
select new {s.ID, s.FirstMidName, s.LastName};
foreach (var student in studentList) {
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}
Console.ReadKey();
}
A consulta de projeção acima exclui o campo EnrollmentDate. Isso tornará seu aplicativo muito mais rápido.