Menu Docs
Página inicial do Docs
/ / /
C#/.NET
/

LINQ

Nesta página

  • Visão geral
  • Tornar uma coleção consultável
  • Estágios de aggregation suportados
  • $project
  • $match
  • $limit
  • $skip
  • $unwind
  • $group
  • $sort
  • $lookup
  • Estágios de agregação não suportados
  • Métodos suportados

Neste guia, você aprenderá a usar o LINQ com o driver .NET/C# do MongoDB. O LINQ permite que você construa consultas em coleções de objetos fortemente digitadas usando palavras-chave e operadores de linguagem. O driver .NET/C# converte automaticamente as query LINQ em operações de agregação.

Os exemplos deste guia usam a restaurants coleção no sample_restaurants banco de dados fornecido nos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster do MongoDB Atlas gratuito e carregar os conjuntos de dados de amostra, consulte a seção Início rápido.

As seguintes classes Restaurant, Address e GradeEntry modelam os documentos nesta coleção:

public class Restaurant
{
public ObjectId Id { get; set; }
public string Name { get; set; }
[BsonElement("restaurant_id")]
public string RestaurantId { get; set; }
public string Cuisine { get; set; }
public Address Address { get; set; }
public string Borough { get; set; }
public List<GradeEntry> Grades { get; set; }
}
public class Address
{
public string Building { get; set; }
[BsonElement("coord")]
public float[] Coordinates { get; set; }
public string Street { get; set; }
[BsonElement("zipcode")]
public string ZipCode { get; set; }
}
public class GradeEntry
{
public DateTime Date { get; set; }
public string Grade { get; set; }
public float Score { get; set; }
}

Observação

Os documentos na coleção restaurants usam a convenção de nomenclatura de camelo. Os exemplos neste guia usam um ConventionPack para desserializar os campos na coleção em maiúsculas e minúsculas Pascal e mapeá-los para as propriedades na classe Restaurant .

Para saber mais sobre serialização personalizada, consulte Serialização personalizada.

Para usar o LINQ para executar uma query na sua coleção, você deve antes criar um objeto IQueryable que se vincule à coleção. Para criar o objeto, use o método AsQueryable() da seguinte forma:

var restaurantsCollection = restaurantsDatabase.GetCollection<Restaurant>("restaurants");
var queryableCollection = restaurantsCollection.AsQueryable();

O método AsQueryable() retorna uma instância IMongoQueryable que tem os métodos de extensão IQueryable, juntamente com um conjunto de métodos específicos do MongoDB.

Depois de ter o objeto consultável, você pode compor uma query usando a sintaxe do método. Alguns estágios do pipeline também oferecem suporte à sintaxe de compreensão de queries, que se assemelha à sintaxe de query SQL.

Selecione a guia Method Syntax ou Query Syntax para ver como compor uma consulta com LINQ:

var query = queryableCollection
.Where(r => r.Name == "The Movable Feast")
.Select(r => new { r.Name, r.Address });
var query = from r in queryableCollection
where r.Name == "The Movable Feast"
select new { r.Name, r.Address };

Você pode imprimir os resultados do exemplo anterior da seguinte maneira:

foreach (var restaurant in query)
{
Console.WriteLine(restaurant.ToJson());
}
{ "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } }

Dica

Acessando os resultados da query

Você também pode acessar os resultados da sua consulta utilizando os métodos ToList() ou ToCursor():

var results = query.ToList();
var results = query.ToCursor();

Você pode usar LINQ para criar um pipeline de agregação. O .NET/C# Driver converte automaticamente cada instrução LINQ nos pipeline de agregação correspondentes. Nesta seção você pode aprender quais estágios do pipeline de agregação são suportados.

Para saber mais sobre as etapas do pipeline de agregação, consulte a página Estágios de agregação no manual do servidor.

O estágio de agregação $project retorna um documento contendo apenas os campos especificados.

Selecione a guia Method Syntax ou Query Syntax para ver como gerar um estágio $project usando LINQ:

var query = queryableCollection
.Select(r => new { r.Name, r.Address });
var query = from r in queryableCollection
select new { r.Name, r.Address };

O resultado do exemplo anterior contém o seguinte documento:

{ "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } }

Observação

Excluindo o campo _id

Se você não incluir o campo _id em sua projeção LINQ, o driver .NET/C# excluirá automaticamente os resultados.

O estágio de agregação $match retorna os documentos que correspondem a um critério especificado.

Selecione a guia Method Syntax ou Query Syntax para ver como gerar um estágio $match usando LINQ:

var query = queryableCollection
.Where(r => r.Name == "The Movable Feast");
var query = from r in queryableCollection
where r.Name == "The Movable Feast"
select r;

O resultado do exemplo anterior contém o seguinte documento:

// Results Truncated
{ "_id" : ObjectId(...), "name" : "The Movable Feast", "restaurant_id" : "40361606", "cuisine" : "American", "address" : {...}, "borough" : "Brooklyn", "grades" : [...] }

O estágio de agregação de $limit limita o número de documentos retornados pela query. O exemplo a seguir mostra como gerar um estágio $limit usando LINQ:

var query = queryableCollection
.Where(r => r.Cuisine == "Italian")
.Select(r => new {r.Name, r.Cuisine})
.Take(5);

O resultado do exemplo anterior contém os seguintes documentos:

{ "name" : "Philadelhia Grille Express", "cuisine" : "Italian" }
{ "name" : "Isle Of Capri Resturant", "cuisine" : "Italian" }
{ "name" : "Marchis Restaurant", "cuisine" : "Italian" }
{ "name" : "Crystal Room", "cuisine" : "Italian" }
{ "name" : "Forlinis Restaurant", "cuisine" : "Italian" }

O estágio de agregação $skip ignora um número específico de documentos retornados por uma query e, em seguida, retorna o restante dos resultados. O exemplo a seguir mostra como gerar um estágio $skip usando LINQ:

var query = queryableCollection
.Where(r => r.Cuisine == "Italian")
.Select(r => new {r.Name, r.Cuisine})
.Skip(2);

O exemplo anterior ignora os dois primeiros restaurantes que correspondem aos critérios e retorna o restante. O resultado contém os seguintes documentos:

// Results Truncated
{ "name" : "Marchis Restaurant", "cuisine" : "Italian" }
{ "name" : "Crystal Room", "cuisine" : "Italian" }
{ "name" : "Forlinis Restaurant", "cuisine" : "Italian" }
...

O estágio de agregação $unwind desconstrói um campo de array especificado e retorna um documento para cada elemento dessa array.

Selecione a guia Method Syntax ou Query Syntax para ver como gerar um estágio $unwind usando LINQ:

var query = queryableCollection
.Where(r => r.Name == "The Movable Feast")
.SelectMany(r => r.Grades);
var query = from r in queryableCollection
where r.Name == "The Movable Feast"
from grade in r.Grades
select grade;

A query no exemplo anterior encontra o documento onde o campo Name tem o valor "The Movable Feast". Em seguida, para cada elemento na array Grades deste documento, a query retorna um novo documento. O resultado contém os seguintes documentos:

{ "date" : ISODate("2014-11-19T00:00:00Z"), "grade" : "A", "score" : 11 }
{ "date" : ISODate("2013-11-14T00:00:00Z"), "grade" : "A", "score" : 2 }
{ "date" : ISODate("2012-12-05T00:00:00Z"), "grade" : "A", "score" : 13 }
{ "date" : ISODate("2012-05-17T00:00:00Z"), "grade" : "A", "score" : 11 }

O estágio de agregação do $group separa os documentos em grupos de acordo com os critérios especificados.

Selecione a guia Method Syntax ou Query Syntax para ver como gerar um estágio $group usando LINQ:

var query = queryableCollection
.GroupBy(r => r.Cuisine)
.Select(g => new { Cuisine = g.Key, Count = g.Count() });
var query = from r in queryableCollection
group r by r.Cuisine into g
select new {Cuisine = g.Key, Count = g.Count()};

O exemplo anterior grupo cada documento pelo valor em seu campo Cuisine e, em seguida, conta quantos documentos têm cada valor Cuisine. O resultado contém os seguintes documentos:

// Results Truncated
{ "cuisine" : "Caribbean", "count" : 657 }
{ "cuisine" : "Café/Coffee/Tea", "count" : 1214 }
{ "cuisine" : "Iranian", "count" : 2 }
{ "cuisine" : "Nuts/Confectionary", "count" : 6 }
{ "cuisine" : "Middle Eastern", "count" : 168 }
...

Observação

Ordem dos resultados

As queries anteriores nem sempre retornam resultados na mesma ordem. A execução deste exemplo pode retornar os resultados em uma ordem diferente da mostrada acima.

O estágio de agregação do $sort retorna os resultados da sua query na ordem especificada.

Selecione a guia Method Syntax ou Query Syntax para ver como gerar um estágio $sort usando LINQ:

var query = queryableCollection
.OrderBy(r => r.Name)
.ThenByDescending(r => r.RestaurantId);
var query = from r in queryableCollection
orderby r.Name, r.RestaurantId descending
select r;

O exemplo anterior retorna os resultados da query classificados alfabeticamente pelo campo Name, com uma classificação descendente secundária no campo RestaurantId. A seguir está um subconjunto dos documentos contidos nos resultados retornados:

// Results Truncated
...
{ "_id" : ObjectId(...), "name" : "Aba Turkish Restaurant", "restaurant_id" : "41548686", "cuisine" : "Turkish", "address" : {...}, "borough" : "Manhattan", "grades" : [...] }
{ "_id" : ObjectId(...), "name" : "Abace Sushi", "restaurant_id" : "50006214", "cuisine" : "Japanese", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] }
{ "_id" : ObjectId(...), "name" : "Abacky Potluck", "restaurant_id" : "50011222", "cuisine" : "Asian", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] }
{ "_id" : ObjectId(...), "name" : "Abaleh", "restaurant_id" : "50009096", "cuisine" : "Mediterranean", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] }
...

O aggregation stage $lookup une documentos de uma coleção a documentos de outra coleção no mesmo database. O estágio $lookup adiciona um novo campo de array a cada documento de entrada. O novo campo de array contém os documentos correspondentes da coleção "entrada".

Observação

Para realizar uma pesquisa, você deve tornar ambas as coleções consultáveis utilizando o método AsQueryable.

Para saber como tornar uma coleção consultável, consulte Tornar uma coleção consultável.

Considere uma segunda coleção no banco de dados sample_restaurants chamada reviews que tenha avaliações de restaurantes. Você pode unir documentos dessa coleção a documentos com o mesmo valor de name na coleção restaurants usando o estágio $lookup.

A seguinte classe Review modela os documentos na collection reviews:

public class Review
{
public ObjectId Id { get; set; }
[BsonElement("restaurant_name")]
public string RestaurantName { get; set; }
public string Reviewer { get; set; }
[BsonElement("review_text")]
public string ReviewText { get; set; }
}

Selecione a guia Method Syntax ou Query Syntax para ver como gerar um estágio $lookup usando LINQ:

var query = queryableCollection
.GroupJoin(reviewCollection,
restaurant => restaurant.Name,
review => review.RestaurantName,
(restaurant, reviews) =>
new { Restaurant = restaurant, Reviews = reviews }
);
var query = from restaurant in queryableCollection
join rv in reviewCollection on restaurant.Name equals rv.RestaurantName into reviews
select new { restaurant, reviews };

O exemplo anterior retorna todos os documentos da coleção restaurants. Cada documento de restaurante tem um campo adicional chamado reviews, que contém todas as avaliações desse restaurante. Uma avaliação corresponde a um restaurante se o valor do campo name no documento da avaliação corresponder ao campo name do documento do restaurante.

O seguinte é um subconjunto dos resultados retornados:

// Results Truncated
{ "restaurant" : {
"_id" : ObjectId("..."),
"name" : "The Movable Feast",
"restaurant_id" : "40361606",
"cuisine" : "American",
"address" : {...},
"borough" : "Brooklyn",
"grades" : [...] },
"reviews" : [
{ "_id" : ObjectId(...), "restaurant_name" : "The Movable Feast", "reviewer" : "Lazlo Cravensworth", "review_text" : "Great restaurant! 12/10 stars!" },
{ "_id" : ObjectId("..."), "restaurant_name" : "The Movable Feast", "reviewer" : "Michael Scarn", "review_text" : "It really was a feast" }
]
}

A implementação do driver MongoDB .NET/C# do LINQ não oferece suporte aos seguintes estágios de agregação:

  • $redact

  • $geoNear

  • $out

Seguem-se alguns dos métodos suportados pela implementação do Driver de LINQ do MongoDB .NET/C#:

Nome do método
Descrição
Any
Determina se algum documento corresponde aos critérios especificados
Average
Calcula a média dos campos especificados
Count
Retorna um Int32 que representa o número de documentos que correspondem aos critérios especificados
LongCount
Retorna um Int64 que representa o número de documentos que correspondem aos critérios especificados
Distinct
Retorna documentos distintos que correspondem aos critérios especificados
First
Retorna o primeiro documento correspondente e joga uma exceção se nenhuma for encontrada
FirstOrDefault
Retorna o primeiro documento correspondente ou null se nenhum for encontrado
GroupBy
Agrupa documentos com base em critérios especificados
GroupJoin
Executa uma ligação externa esquerda para outra coleção no mesmo banco de dados
Max
Retorna o documento com o valor máximo especificado
OfType
Retorna documentos que correspondem ao tipo especificado
OrderBy, OrderByDescending
Retorna resultados em uma ordem de classificação especificada
ThenBy, ThenByDescending
Permite que uma classificação secundária seja especificada
Select
Seleciona documentos com base em critérios especificados
SelectMany
Projeta cada elemento de uma sequência e combina as sequências resultantes em um documento
Single
Retorna o único documento correspondente e joga uma exceção se não houver exatamente um documento
SingleOrDefault
Retorna um único documento correspondente ou null se nenhum documento corresponder
Skip
Ignora um número especificado de documentos e retorna o restante dos resultados
Sum
Retorna a soma dos valores em um campo especificado
Take
Especifica o número de resultados a serem retornados
Where
Retorna todos os documentos que correspondem aos critérios especificados

Voltar

Agregação