Consulta e Localização de Entidades

Este tópico abrange as várias formas de consultar dados usando o Entity Framework, incluindo o LINQ e o método Finify. As técnicas apresentadas neste tópico aplicam-se igualmente a modelos criados com o Code First e o EF Designer.

Encontrar entidades através de uma consulta

O DbSet e o IDbSet implementam o IQueryable e, por isso, podem ser usados como ponto de partida para escrever uma consulta LINQ na base de dados. Este não é o local apropriado para uma discussão aprofundada sobre o LINQ, mas aqui ficam alguns exemplos simples:

using (var context = new BloggingContext())
{
    // Query for all blogs with names starting with B
    var blogs = from b in context.Blogs
                   where b.Name.StartsWith("B")
                   select b;

    // Query for the Blog named ADO.NET Blog
    var blog = context.Blogs
                    .Where(b => b.Name == "ADO.NET Blog")
                    .FirstOrDefault();
}

Note-se que o DbSet e o IDbSet criam sempre consultas contra a base de dados e envolvem sempre uma ida e volta à base de dados, mesmo que as entidades devolvidas já existam no contexto. Uma consulta é executada contra a base de dados quando:

  • É enumerado por uma instrução foreach (C#) ou For Each (Visual Basic).
  • É enumerado por uma operação de coleção, como ToArray, ToDictionary ou ToList.
  • Operadores LINQ como First ou Any são especificados na parte mais externa da consulta.
  • Os seguintes métodos são chamados: Load método de extensão num DbSet, DbEntityEntry.Reload e Database.ExecuteSqlCommand.

Quando os resultados são devolvidos da base de dados, objetos que não existem no contexto são anexados ao contexto. Se um objeto já estiver no contexto, o objeto existente é devolvido (os valores atuais e originais das propriedades do objeto na entrada não são sobrescritos pelos valores da base de dados).

Quando realiza uma consulta, as entidades que foram adicionadas ao contexto mas ainda não foram guardadas na base de dados não são devolvidas como parte do conjunto de resultados. Para obter os dados que estão no contexto, veja Dados Locais.

Se uma consulta não devolver linhas da base de dados, o resultado será uma coleção vazia, em vez de nula.

Encontrar entidades usando chaves primárias

O método Find no DbSet usa o valor da chave primária para tentar encontrar uma entidade rastreada pelo contexto. Se a entidade não for encontrada no contexto, será enviada uma consulta para a base de dados para encontrar a entidade aí. O valor nulo é devolvido se a entidade não for encontrada no contexto ou na base de dados.

O Find difere do uso de uma consulta em dois aspetos significativos:

  • Uma ida e volta à base de dados só será feita se a entidade com a chave dada não for encontrada no contexto.
  • A função Find irá devolver as entidades que estão no estado 'Adicionado'. Ou seja, o Find devolverá entidades que foram adicionadas ao contexto mas ainda não foram guardadas na base de dados.

Encontrar uma entidade por chave primária

O código seguinte mostra algumas utilizações de Find:

using (var context = new BloggingContext())
{
    // Will hit the database
    var blog = context.Blogs.Find(3);

    // Will return the same instance without hitting the database
    var blogAgain = context.Blogs.Find(3);

    context.Blogs.Add(new Blog { Id = -1 });

    // Will find the new blog even though it does not exist in the database
    var newBlog = context.Blogs.Find(-1);

    // Will find a User which has a string primary key
    var user = context.Users.Find("johndoe1987");
}

Encontrar uma entidade por chave primária composta

O Entity Framework permite que as suas entidades tenham chaves compostas – ou seja, uma chave composta por mais do que uma propriedade. Por exemplo, pode ter uma entidade BlogSettings que representa as definições de um utilizador para um blog específico. Como um utilizador só teria uma BlogSettings para cada blog, podias escolher fazer da chave primária de BlogSettings uma combinação de BlogId e Nome de Utilizador. O código seguinte tenta encontrar as BlogSettings com BlogId = 3 e Username = "johndoe1987":

using (var context = new BloggingContext())
{
    var settings = context.BlogSettings.Find(3, "johndoe1987");
}

Note que, quando tem chaves compostas, precisa de usar o ColumnAttribute ou a API fluente para especificar uma ordem para as propriedades da chave composta. A chamada para Encontrar deve usar esta ordem ao especificar os valores que formam a chave.