Visão geral
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.
Dados de amostra
Os exemplos neste guia usam a coleção planets do banco de dados sample_guides . Os documentos nesta coleção utilizam a seguinte classe Planet como um 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; } }
This collection is from the sample datasets provided by Atlas. See the Get Started with the EF Core Provider guide to learn how to create a free MongoDB cluster and load this sample data.
Encontrar entidades
Encontre uma única entidade usando o método FirstOrDefault() ou encontre múltiplas entidades usando o método Where() .
Encontre uma única entidade
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);
Encontrar múltiplas entidades
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); }
Executar query de uma propriedade de sombra
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); }
Entidades de classificação
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); }
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); }
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.
Limite o número de resultados
Use o método Take() para especificar um número máximo de entidades a 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); }
Ignorar resultados
Use o método Skip() para especificar um número de entidades a serem ignoradas antes de retornar os 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); }
Agregações escalares
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 predicadoLongCount(): retorna o número de elementos em uma coleção comolongou o número de documentos que correspondem a um predicadoAny(): retornatruese algum elemento em uma coleção corresponder ao predicadoMax(): retorna o valor máximo de um campo especificado em uma coleçãoMin(): retorna o valor mínimo de um campo especificado em uma coleçãoSum(): retorna a soma de valores de um campo especificado em uma coleçãoAverage(): 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.
Contar
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);
LongCount
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);
Any
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);
Máx
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);
Min
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);
Soma
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);
Média
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);
Inspecione as queries enviadas ao MongoDB
Depois de gravar uma query LINQ, inspecione a query gerada para confirmar que o provedor está enviando a forma esperada para o MongoDB Server. Para inspecionar query durante o desenvolvimento, habilite o log do EF Core em seu DbContext usando o método LogTo().
O exemplo a seguir mostra como habilitar o registro em log no console ao criar um objeto DbContext:
var mongoClient = new MongoClient("<connection string URI>"); var dbContextOptions = new DbContextOptionsBuilder<MyDbContext>() .UseMongoDB(mongoClient, "sample_guides") .LogTo(Console.WriteLine) .Options; var db = new MyDbContext(dbContextOptions);
Habilitar registro de dados confidenciais
O provedor registra o texto completo da query MQL somente quando o registro de dados confidenciais está ativado. Se você não ativar o registro de dados confidenciais, os logs de query poderão omitir valores. Para ativar o registro de dados confidenciais, chame o método EnableSensitiveDataLogging() do seu objeto DbContextOptionsBuilder, conforme o exemplo a seguir:
var mongoClient = new MongoClient("<connection string URI>"); var dbContextOptions = new DbContextOptionsBuilder<MyDbContext>() .UseMongoDB(mongoClient, "sample_guides") .LogTo(Console.WriteLine) .EnableSensitiveDataLogging() .Options; var db = new MyDbContext(dbContextOptions);
Importante
Evitar na produção
Habilite o log de dados confidenciais apenas em ambientes de desenvolvimento.
Convenções de serialização personalizadas
Se você registrar convenções de serialização BSON personalizadas no MongoClient, como a nomenclatura 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 provedor EF Core usa nomes de propriedade de entidade para gerar MQL, portanto, uma incompatibilidade pode fazer com que as query direcionem os campos errados e ignorem quaisquer índices nesses campos. Quando os nomes de campo armazenados diferem dos nomes de propriedade da entidade, você pode mapear explicitamente uma propriedade para o nome de 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 driver .NET/C#
If you need lower-level visibility into MongoDB commands, you can use the .NET/C# Driver monitoring APIs on your MongoClient object. To learn more about these APIs, see Monitoring in the .NET/C# Driver documentation.
Informações adicionais
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 EF Core discutidos nesta guia, consulte os seguintes links de documentação da API .NET:
Para saber mais sobre os métodos do driver .NET/C# usados nesta página, consulte os seguintes links da documentação da API:
Para saber mais sobre o método HasElementName(), consulte o seguinte link da documentação da API do EF Core Provider: