LINQ
Nesta página
Visão geral
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; } [ ] 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; } [ ] public float[] Coordinates { get; set; } public string Street { get; set; } [ ] 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.
Tornar uma coleção consultável
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();
Estágios de aggregation suportados
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.
$project
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.
$match
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" : [...] }
$limit
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" }
$skip
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" } ...
$unwind
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 }
$group
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.
$sort
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" : [...] } ...
$lookup
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; } [ ] public string RestaurantName { get; set; } public string Reviewer { get; set; } [ ] 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" } ] }
Estágios de agregação não suportados
A implementação do driver MongoDB .NET/C# do LINQ não oferece suporte aos seguintes estágios de agregação:
$redact
$geoNear
$out
Métodos suportados
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 |