Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Menu Docs
Página inicial do Docs
/ /
/ / /

Localizar e query dados de entidade com LINQ

O Entity Framework Core permite que você trabalhe com dados em seu aplicação sem executar os comandos do banco de dados de dados explicitamente. Para consultar seus dados, use a sintaxe Query integrada da linguagem (LINQ). O LINQ permite que você escreva queries fortemente digitadas usando palavras-chave e operadores específicos do C#. Quando você executa o aplicação, o EF Core Provider traduz automaticamente as queries do LINQ e as executa no banco de banco de dados usando a MongoDB Query API.

Neste guia, você pode ver exemplos de operações de query comuns em um aplicação configurado para usar o EF Core Provider.

Dica

Para saber como configurar um aplicação para usar o fornecedor do EF Core, consulte Configurar o fornecedor do EF Core.

Os exemplos nesta guia usam a coleção planets do banco de dados do sample_guides . Os documentos nesta coleção utilizam a seguinte classe Planet como modelo:

public class Planet
{
public ObjectId _id { get; set; }
public string name { get; set; } = null!;
public int orderFromSun { get; set; }
public bool hasRings { get; set; }
}

Esta coleção é dos conjuntos de dados de amostra fornecidos pelo Atlas. Consulte o guia Início rápido para saber como criar um cluster MongoDB gratuito e carregar esses dados de amostra.

Encontre uma única entidade usando o método FirstOrDefault() ou encontre múltiplas entidades usando o método Where() .

O método FirstOrDefault() retorna a primeira entidade que encontra na sua collection que corresponda aos critérios de pesquisa e retorna null se nenhuma entidade correspondente for encontrada.

O código a seguir usa o método FirstOrDefault() para localizar um planeta com o campo name de "Mercury" de um DBSet chamado Planets e imprime o nome do planeta no console:

var planet = db.Planets.FirstOrDefault(p => p.name == "Mercury");
Console.WriteLine(planet?.name);

Você pode utilizar o método Where() para recuperar múltiplas entidades de sua collection. Where() retorna todas as entidades que correspondem aos critérios de pesquisa.

O código a seguir usa o método Where() para encontrar todos os planetas que têm o campo hasRings definido como true e imprime os nomes dos planetas no console.

var planets = db.Planets.Where(p => p.hasRings);
foreach (var p in planets)
{
Console.WriteLine(p.name);
}

Uma propriedade shadow é uma propriedade que não está definida em sua classe de entidade .NET, mas está incluída no modelo Entity Framework e mapeada para campos no banco de dados. Você pode usar propriedades de sombra para query ou acompanhar dados em seus documentos sem expô-los como uma propriedade em sua entidade.

Para fazer referência a uma propriedade de sombra em uma query LINQ, chame o método EF.Property<T>() e passe o nome da propriedade configurada como um argumento. O argumento de tipo genérico deve corresponder ao tipo de dados da propriedade shadow .

Por exemplo, a classe Planet não define uma propriedade para o campo mainAtmosphere. Para configurar este campo como uma propriedade de sombra, chame o método Property<T>() no método OnModelCreating() de PlanetDbContext, como mostrado no seguinte exemplo:

public class PlanetDbContext : DbContext
{
public DbSet<Planet> Planets { get; init; } = null!;
public static PlanetDbContext Create(IMongoDatabase database) =>
new(new DbContextOptionsBuilder<PlanetDbContext>()
.UseMongoDB(database.Client, database.DatabaseNamespace.DatabaseName)
.Options);
public PlanetDbContext(DbContextOptions options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Planet>().ToCollection("planets");
modelBuilder.Entity<Planet>().Property<string[]>("mainAtmosphere");
}
}

A chamada para modelBuilder.Entity<Planet>().Property<string[]>("mainAtmosphere") instrui a framework a incluir mainAtmosphere no modelo e mapeá-lo para um campo string[] no MongoDB.

O código a seguir usa o método EF.Property<string[]>() para localizar todos os planetas que têm uma propriedade shadow mainAtmosphere não vazia e imprime os nomes dos planetas no console:

var planets = db.Planets.Where(
p => EF.Property<string[]>(p, "mainAtmosphere").Length > 0);
foreach (var p in planets)
{
Console.WriteLine(p.name);
}

Utilize o método OrderBy() para especificar uma ordem na qual retornar entidades de uma query. OrderBy() classifica os elementos em ordem crescente com base em critérios de classificação especificados.

O código a seguir usa o método OrderBy() para encontrar todos os planetas e classificá-los pelo valor do campo orderFromSun em ordem crescente. Em seguida, ele imprime os resultados no console.

var planetList = db.Planets.OrderBy(p => p.orderFromSun);
foreach (var p in planetList)
{
Console.WriteLine(p.name);
}
{"_id":"...","name":"Mercury","orderFromSun":1,"hasRings":false}
{"_id":"...","name":"Venus","orderFromSun":2,"hasRings":false}
{"_id":"...","name":"Earth","orderFromSun":3,"hasRings":false}
{"_id":"...","name":"Mars","orderFromSun":4,"hasRings":false}
{"_id":"...","name":"Jupiter","orderFromSun":5,"hasRings":true}
{"_id":"...","name":"Saturn","orderFromSun":6,"hasRings":true}
{"_id":"...","name":"Uranus","orderFromSun":7,"hasRings":true}
{"_id":"...","name":"Neptune","orderFromSun":8,"hasRings":true}

Dica

Classificar em ordem decrescente

Você pode classificar os resultados de uma query em ordem decrescente utilizando o método OrderByDescending() .

Você pode executar uma classificação secundária em sua query usando o método ThenBy() . O método ThenBy() classifica os resultados do método OrderBy() em ordem crescente com base em critérios de classificação especificados. O método ThenBy() deve ser encadeado ao método OrderBy() .

Dica

Classificação secundária em ordem decrescente

Você pode executar uma classificação secundária em ordem decrescente usando o método ThenByDescending() .

O código a seguir usa os métodos OrderBy() e ThenBy() para encontrar todos os planetas e classificá-los pelo campo hasRings() , com uma classificação secundária no campo name .

var planetList = db.Planets.OrderBy(o => o.hasRings).ThenBy(o => o.name);
foreach (var p in planetList)
{
Console.WriteLine("Has rings: " + p.hasRings + ", Name: " + p.name);
}
{"_id":"...","name":"Earth","orderFromSun":3,"hasRings":false}
{"_id":"...","name":"Mars","orderFromSun":4,"hasRings":false}
{"_id":"...","name":"Mercury","orderFromSun":1,"hasRings":false}
{"_id":"...","name":"Venus","orderFromSun":2,"hasRings":false}
{"_id":"...","name":"Jupiter","orderFromSun":5,"hasRings":true}
{"_id":"...","name":"Neptune","orderFromSun":8,"hasRings":true}
{"_id":"...","name":"Saturn","orderFromSun":6,"hasRings":true}
{"_id":"...","name":"Uranus","orderFromSun":7,"hasRings":true}

Dica

Ao ordenar em campos com um valor booleano, as entidades com um valor de campo de false são exibidas antes daquelas com um valor de true.

Utilize o método Take() para especificar um número máximo de entidades para retornar de uma query.

O código a seguir usa o método Take() para retornar os primeiros 3 planetas da coleção Planets:

var planetList = db.Planets.Take(3);
foreach (var p in planetList)
{
Console.WriteLine(p.name);
}

Utilize o método Skip() para especificar uma série de entidades a serem ignoradas antes de retornar resultados de uma query.

O código a seguir usa os métodos OrderBy() e Skip() para ignorar os primeiros 5 planetas (ordenados por orderFromSun) e retornar os planetas restantes:

var planetList = db.Planets.OrderBy(p => p.orderFromSun).Skip(5);
foreach (var p in planetList)
{
Console.WriteLine(p.name);
}

O EF Core Provider oferece suporte aos seguintes métodos de agregação escalar:

  • Count(): retorna o número de elementos em uma coleção ou o número de documentos que correspondem a um predicado

  • LongCount(): retorna o número de elementos em uma coleção como long ou o número de documentos que correspondem a um predicado

  • Any(): retorna true se algum elemento em uma coleção corresponder ao predicado

  • Max(): retorna o valor máximo de um campo especificado em uma coleção

  • Min(): retorna o valor mínimo de um campo especificado em uma coleção

  • Sum(): retorna a soma de valores de um campo especificado em uma coleção

  • Average(): retorna a média de valores de um campo especificado em uma coleção

As seções a seguir mostram exemplos de cada um dos métodos anteriores.

O exemplo seguinte utiliza o método Count() para contar o número de elementos na collection Planets:

var planetCount = db.Planets.Count();
Console.WriteLine("Planet Count: " + planetCount);

O exemplo seguinte utiliza o método Count() para contar o número de elementos na coleção Planets que têm um campo hasRings configurado para true:

var planetCountWithRings = db.Planets.Count(p => p.hasRings);
Console.WriteLine("Planet Count with Rings: " + planetCountWithRings);

O exemplo seguinte utiliza o método LongCount() para contar o número de elementos na coleção Planets e retorna o resultado como um long:

var planetCountLong = db.Planets.LongCount();
Console.WriteLine("Long Planet Count: " + planetCountLong);

O exemplo seguinte utiliza o método LongCount() para contar o número de elementos na coleção Planets que têm um campo hasRings configurado para true e retorna o resultado como long:

var planetCountLongWithRings = db.Planets.LongCount(p => p.hasRings);
Console.WriteLine("Long Planet Count with Rings: " + planetCountLongWithRings);

O exemplo seguinte utiliza o método Any() para verificar se algum elemento na coleção Planets tem um campo hasRings configurado para true:

var results = db.Planets.Any(p => p.hasRings);
Console.WriteLine("Planet with Rings: " + results);

O exemplo seguinte utiliza o método Max() para localizar o valor máximo do campo orderFromSun na collection Planets:

var furthestPlanet = db.Planets.Max(p => p.orderFromSun);
Console.WriteLine("Furthest Planet: " + furthestPlanet);

O exemplo seguinte utiliza o método Min() para localizar o valor mínimo do campo orderFromSun na collection Planets:

var closestPlanet = db.Planets.Min(p => p.orderFromSun);
Console.WriteLine("Closest Planet: " + closestPlanet);

O exemplo a seguir utiliza o método Sum() para localizar a soma do campo orderFromSun na coleção Planets:

var totalOrderFromSun = db.Planets.Sum(p => p.orderFromSun);
Console.WriteLine("Total Order From Sun: " + totalOrderFromSun);

O exemplo seguinte utiliza o método Average() para localizar o valor médio do campo orderFromSun na collection Planets:

var averageOrderFromSun = db.Planets.Average(p => p.orderFromSun);
Console.WriteLine("Average Order From Sun: " + averageOrderFromSun);

Depois de escrever uma query LINQ, inspecione a query gerada para confirmar que o provedor está enviando a forma esperada para o MongoDB Server. Para inspecionar queries durante o desenvolvimento, habilite o registro do EF Core DbContext no seu utilizando o método LogTo().

O exemplo a seguir mostra como ativar o registro no console ao criar um objeto DbContext :

var mongoClient = new MongoClient("<connection string URI>");
var dbContextOptions =
new DbContextOptionsBuilder<MyDbContext>()
.UseMongoDB(mongoClient, "<database name>")
.LogTo(Console.WriteLine)
.Options;
var db = new MyDbContext(dbContextOptions);

O fornecedor registra o texto completo da query MQL somente quando o registro de dados confidenciais está habilitado. Se você não habilitar o registro de dados confidenciais, os registros de query poderão omitir valores. Para habilitar o registro de dados confidenciais, chame o método EnableSensitiveDataLogging() a partir do seu DbContextOptionsBuilder objeto, conforme mostrado no exemplo a seguir:

var mongoClient = new MongoClient("<connection string URI>");
var dbContextOptions =
new DbContextOptionsBuilder<MyDbContext>()
.UseMongoDB(mongoClient, "<database name>")
.LogTo(Console.WriteLine)
.EnableSensitiveDataLogging()
.Options;
var db = new MyDbContext(dbContextOptions);

Importante

Evitar em produção

Habilite o registro de dados confidenciais somente em ambientes de desenvolvimento.

Se você registrar convenções de serialização BSON personalizadas no MongoClient, como nomeação de campo camel-case, essas convenções poderão alterar os nomes de campo armazenados no MongoDB para que eles sejam diferentes dos nomes de propriedade em seu modelo de entidade. O EF Core Provider usa nomes de propriedade de entidade para gerar MQL, portanto, uma incompatibilidade pode fazer com que as queries tenham como alvo os campos errados e ignorem quaisquer índices nesses campos. Quando os nomes dos campo armazenados forem diferentes dos nomes das propriedade da entidade, você poderá mapear explicitamente uma propriedade para o nome do campo armazenado em OnModelCreating() usando HasElementName(), conforme mostrado no exemplo a seguir:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Planet>()
.Property(p => p.name)
.HasElementName("name");
}

Dica

APIs de monitoramento de drivers .NET/C#

Se você precisar de visibilidade de nível inferior nos comandos do MongoDB , poderá usar as APIs de monitoramento de driver .NET/C# no seu MongoClient objeto. Para saber mais sobre essas APIs, consulte Monitoramento na documentação do driver .NET/C#.

Para saber mais sobre aggregations no MongoDB, consulte o guia Operações de agregação no manual do MongoDB Server.

Para saber mais sobre os métodos do EF Core discutidos neste guia, consulte os seguintes links de documentação da API do .NET :

Para saber mais sobre os métodos do driver .NET/C# usados nesta página, consulte os seguintes links de documentação da API:

Para saber mais sobre o método HasElementName(), consulte o seguinte link de documentação da API do provedor principal da EF:

Voltar

Configuração