Back-End

25 set, 2015

Curso Entity Framework – Consultando o modelo de entidades

Publicidade

Nesta aula vamos mostrar como podemos consultar o modelo de entidades (aula anterior).

Podemos consultar o modelo de entidades de 3 formas distintas, usando:

  1. LINQ to Entities
  2. Entity SQL
  3. Native SQL

1. LINQ to Entities

LINQ to Entities é uma versão especializada da LINQ, que opera em modelos do Entity Framework sendo a sua principal linguagem de consulta. Através dela podemos realizar projeções, agrupar, ordenar e realizar junções no modelo de entidades.

macoratti16

A sintaxe usada pela LINQ to Entities é mais fácil de aprender e assimilar do que a Entity SQL. Existem dois tipos de sintaxe que podemos usar com LINQ-to-Entities:

  • A sintaxe do método LINQ com expressões lambdas:

Using ctx As New EscolaDBEntities
        Dim consulta = ctx.Alunos.Where(Function(a) a.AlunoNome = "Macoratti")
   End Using
  • A sintaxe de consulta LINQ:
 Using ctx As New EscolaDBEntities

      Dim consulta = From _aluno In ctx.Alunos
                          Where _aluno.AlunoNome = "Macoratti"
                          Select _aluno
   End Using

Nota: As consultas acima foram feitas usando o modelo de entidades criado na aula 3.

O que são Expressões Lambda?

As expressões lambda foram incluídas na plataforma .NET para dar suporte a consultas LINQ onde as cláusulas Where são compiladas como expressões lambdas. Elas podem ser consideradas uma forma de delegate, que pode passar ou retornar outra função.

Nota: Delegates permitem que uma classe use métodos de outra classe. Para saber mais sobre delegates, leia o meu artigo: Usando Delegates.

Assim, as expressões lambdas são funções ou rotinas, sem nome, que calculam e retornam um valor único. Elas podem ser usadas em qualquer lugar que um tipo delegate for válido.

Na linguagem C#, todas as expressões lambda usam o operador lambda =>, que é lido como “vai para”.

  • O lado esquerdo do operador lambda especifica os parâmetros de entrada (se houver);
  • O lado direito contém a expressão ou o bloco de instruções.

A expressão lambda x => x * x é lida assim: “x recebe x vezes x”.

Primeiro, criamos o objeto da classe de contexto que é EscolaDBEntities. Devemos inicializá-lo usando a cláusula using, de modo que assim que sua utilização estiver fora do escopo ele irá chamar automaticamente o método Dispose() da classe DBContext liberando os recursos usados. O retorno será do tipo IQueryable.

LINQ-to-Entities e LINQ-to-Objects não são a mesma coisa ?

LINQ-to-Objects é um conjunto de métodos de extensão em IEnumerable<T> que permitem a realização de operações de consulta em memória em sequências arbitrárias de objetos. Os métodos aceitam delegados simples, quando necessário.

LINQ-to-Entities é um provedor LINQ que tem um conjunto de métodos de extensão emIQueryable<T>. Os métodos constroem uma árvore de expressão (é por isso que os delegados são passados como Expression<>s), e o provedor vai construir uma consulta SQL com base na análise desta árvore de expressão (http://msdn.microsoft.com/en-us/library/bb386964.aspx).

2. Entity SQL

A Entity SQL é outra forma de criar uma consulta. Ela é processada diretamente pelo Object Services do Entity Framework e retorna um ObjectQuery, ao invés de um IQueryable. Ela é uma derivação da Transact-SQL, projetada para consultar e manipular entidades definidas no EDM, e dá suporte à herança e à associação, sendo que tanto os componentes Object Services, como os componentes Entity Client podem executar instruções Entity SQL.

A linguagem Entity SQL é semelhante à SQL e permite que você consulte modelos conceituais no Entity Framework. Os modelos conceituais representam dados como entidades e relações; e a linguagem Entity SQL permite que você consulte essas entidades e relações em um formato que seja familiar às pessoas que já conhecem a SQL.

Nota: O Object Services permite realizar consultas, atualizações, inclusões e exclusões nos dados, expressados como objetos CLR fortemente tipados que são instâncias de entity types. Ele dá suporte tanto às consultas Entity SQL, quanto ao LINQ to Entities.

Abaixo temos uma figura onde vemos os Object Services na composição do Entity Framework:

ef_curb51

Para criar consultas com Entity SQL precisamos do ObjectContext:

Imports System.Data.Entity.Infrastructure
Imports System.Data.Entity.Core.Objects
        Dim consulta As String = "SELECT VALUE alu FROM EscolaDBEntities.Alunos AS alu WHERE alu.AlunoNome = 'Macoratti'"
        Dim objctx = TryCast(ctx, IObjectContextAdapter).ObjectContext
        Dim _aluno As ObjectQuery(Of Aluno) = objctx.CreateQuery(Of Aluno)(consulta)
        Dim novoAluno As Aluno = _aluno.First(Of Aluno)()

Podemos ainda usar o EntityConnection e EntityCommand para executar uma consulta Entity SQL:

Imports System.Data.Entity.Core.EntityClient
        Using con = New EntityConnection("name=EscolaDBEntities")
            con.Open()
            Dim cmd As EntityCommand = con.CreateCommand()
            cmd.CommandText = "SELECT VALUE alu FROM EscolaDBEntities.Alunos AS alu where alu.AlunoNome='Macoratti'"
            Dim dict As New Dictionary(Of Integer, String)()
            Using rdr As EntityDataReader = cmd.ExecuteReader(CommandBehavior.SequentialAccess Or CommandBehavior.CloseConnection)
                While rdr.Read()
                    Dim a As Integer = rdr.GetInt32(0)
                    Dim b = rdr.GetString(1)
                    dict.Add(a, b)
                End While
            End Using
        End Using

Um EntityDataReader não retorna um ObjectQuery. Ele retorna dados em linhas e colunas.

Uma EntityConnection não é uma conexão com um banco de dados. Embora você possa abrir e fechar uma EntityConnection, isso não significa que você está abrindo e fechando uma conexão com um banco de dados. Se você usar o EntityClient diretamente ou deixar que os Object Services executem os seus comandos e consultas, a EntityConnection será apenas um caminho para a conexão com o banco de dados.

Uma EntityConnection é composto por 4 partes:

  1. MetaData – o ponteiro para os arquivos de metadados CSDL, MSL e SSDL;
  2. Provider Connection – a string de conexão com o banco de dados;
  3. Provider Name – o namespace do provedor do banco de dados;
  4. Name – o nome da string de conexão.

Você pode definir a EntityConnection declarativamente no arquivo de configuração (app.config ou web.config).

Um EntityCommand representa um comando para ser executado em um modelo de dados de entidades (EDM).

3. Native SQL

Às vezes, executar um SQL nativo customizado é a maneira mais eficiente de realizar uma consulta diretamente no banco de dados. Abaixo vemos uma consulta usando SQL nativo sendo executada via método SqlQuery:

Using ctx = New EscolaDBEntities()
            Dim nomeDoAluno = ctx.Alunos.SqlQuery("Select alunoId, alunoNome, padraoId from Alunos where alunoNome='Macoratti'").FirstOrDefault(Of Aluno)()
        End Using

O método SqlQuery cria uma consulta de SQL puro, que irá retornar elementos do tipo genérico dado. O tipo pode ser qualquer um que tenha propriedades que correspondam aos nomes das colunas retornadas da consulta, ou pode ser um tipo primitivo simples. O tipo não tem que ser um tipo de entidade. Os resultados desta consulta nunca são rastreados pelo contexto, mesmo que o tipo de objeto retornado seja um tipo de entidade.

Nota: A partir do Entity Framework 5, temos o método ExecuteSqlCommand, que pode ser usado para executar comandos SQL puros. Em versões anteriores do Entity Framerwork, você poderá usar o seguinte método da ObjectContext: objectContext.ExecuteStoreQuery <return-type> (SQL puro).

Nas aulas futuras veremos como executar SQL puro usando o DBContext.

Na próxima aula vamos tratar da abordagem Code-First no Entity Framework.