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
/ /
/ / /

Relacionamentos incorporados e referências manuais

Neste guia, você pode aprender como usar o MongoDB Entity Framework Core Provider para modelar relacionamentos entre documentos em seu banco de dados MongoDB . O fornecedor do EF Core oferece suporte aos seguintes tipos de relacionamento :

  • Relacionamentos incorporados: subdocumentos incorporados diretamente em um documento pai. Essa é a abordagem recomendada para relacionamentos um-para-um e um-para-muitos no MongoDB.

  • Referências manuais: um documento que faz referência a outro documento armazenando sua ID em um campo, em vez de incorporar o documento como um subdocumento. Essa abordagem funciona bem para modelar relacionamentos de muitos para muitos ou quando você precisa acessar os documentos de forma independente.

Dica

Crie seu esquema para padrões de query

Ao modelar dados para o MongoDB, primeiro determine as operações que seu aplicação executa com mais frequência. Em seguida, escolha uma estrutura de documento que ofereça suporte a essas operações de forma eficiente. O esquema mais eficiente no MongoDB pode não corresponder ao esquema que você usaria em um banco de dados relacional. Em vez disso, considere quais dados são comumente recuperados juntos, quais valores mudam com frequência e quais relacionamentos de dados mudam com o tempo.

Para saber mais sobre modelagem de dados e migração de um banco de dados relacional para o MongoDB Server, consulte o Gráfico de Mapeamento de SQL para MongoDB e Modelagem de Dados no MongoDB na documentação do MongoDB Server .

Para incorporar um subdocumento em um documento pai, especifique o modelo para o documento incorporado como uma entidade própria. Os relacionamentos incorporados são a maneira nativa do MongoDB de modelar relacionamentos e oferecer melhor desempenho para documentos que você acessa com frequência juntos.

Use documentos incorporados quando os dados relacionados forem geralmente exibidos no contexto de seu pai e quando os dados incorporados permanecerem razoávelmente limitados em tamanho. Isso inclui pequenos conjuntos de valores filhos, como endereços, configurações ou uma lista limitada de itens recentes. Quando você incorpora documentos, o MongoDB Server pode melhorar o desempenho recuperando dados relacionados em uma única operação de banco de dados e atualizando os dados relacionados atomicamente em um único documento.

Considere incorporar dados nos seguintes casos:

  • Seu aplicação geralmente lê dados pai e filho juntos. Buscar tudo em uma query é mais eficiente do que fazer chamadas separadas.

  • Os dados relacionados não crescem sem um limite superior claro. Dados limitados não farão com que os documentos aumentem indefinidamente ou atinjam o limite de tamanho de documento de 16MB do MongoDB.

  • Os dados relacionados não mudam com frequência e independentemente do pai. Isso gera menos sobrecarga ao reescrever o documento principal.

Observação

Hierarquias agrupadas

Quando você atualiza qualquer propriedade de uma entidade de propriedade aninhada, o provedor de núcleo da EF reescreve todo o documento raiz. Para hierarquias de entidade com três ou mais níveis de aninhamento, este custo de escrita é composto, porque uma pequena alteração profunda na árvore aciona uma reescrita completa do documento pai. Se o seu modelo usar o aninhamento profundo e seu aplicação executar gravações frequentes, considere o nivelamento da hierarquia ou a substituição de entidades de propriedade internas por referências manuais.

Para saber mais,consulte Dados incorporados na documentação do MongoDB Server .

Você pode designar uma entidade própria das seguintes maneiras:

  • Atributo [Owned]: Aplique o [Owned] atributo de anotação de dados à classe de modelo do subdocumento. Essa abordagem é declarativa e concisa, mas também menos flexível, porque se aplica globalmente a todos os usos do tipo próprio.

  • API fluente: Chame OwnsOne() os OwnsMany() métodos ou na sua DbContext configuração do. Essa abordagem oferece mais controle e flexibilidade, permitindo que você configure o relacionamento de forma diferente para entidades específicas sem modificar a classe do modelo.

As seções a seguir fornecem exemplos dessas abordagens para modelar entidades de propriedade única e múltipla.

Para incorporar um único documento dentro de um documento pai, chame o método OwnsOne() em sua configuração do DbContext ou aplique o atributo [Owned] à classe incorporada.

O exemplo a seguir mostra uma entidade Customer que contém um documento Address incorporado. Selecione a aba [Owned] Attribute ou Fluent API para ver a sintaxe correspondente :

[Owned]
public class Address
{
public string Street { get; set; } = null!;
public string City { get; set; } = null!;
public string Country { get; set; } = null!;
}
public class Customer
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public Address Address { get; set; } = null!;
}
public class CustomerDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; } = null!;
public CustomerDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>(c =>
{
c.OwnsOne(c => c.Address);
c.ToCollection("customers");
});
}
}

Quando você salva uma entidade Customer, o MongoDB armazena o Address como um documento incorporado dentro do documento Customer. O seguinte JSON mostra como esse relacionamento aparece no MongoDB:

{
"_id": ObjectId("..."),
"Name": "John Doe",
"Address": {
"Street": "123 Main St",
"City": "New York",
"Country": "USA"
}
}

Para incorporar vários documentos em um documento pai , chame o método OwnsMany() ou aplique o atributo [Owned] à classe incorporada e defina uma propriedade de coleção .

O exemplo a seguir mostra uma entidade Customer que contém vários documentos Order incorporados. Selecione a aba [Owned] Attribute ou Fluent API para ver a sintaxe correspondente:

[Owned]
public class Order
{
public string Product { get; set; } = null!;
public int Quantity { get; set; }
}
public class CustomerWithOrders
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public List<Order> Orders { get; set; } = new();
}
public class OrderDbContext : DbContext
{
public DbSet<CustomerWithOrders> Customers { get; set; } = null!;
public OrderDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CustomerWithOrders>(c =>
{
c.OwnsMany(c => c.Orders);
c.ToCollection("customers");
});
}
}

Quando você salva uma entidade CustomerWithOrders, o MongoDB armazena o Orders como uma array de documentos incorporados, conforme mostrado no JSON a seguir:

{
"_id": ObjectId("..."),
"Name": "Jane Smith",
"Orders": [
{ "Product": "Laptop", "Quantity": 1 },
{ "Product": "Mouse", "Quantity": 2 }
]
}

Para modelar relacionamentos entre entidades que não são incorporadas, você pode armazenar referências manualmente salvando a ID de um documento em um campo de outro documento. Essa abordagem exige que você gerencie o relacionamento no código do aplicação .

Use referências ao consultar regularmente os dados relacionados independentemente de seu pai, quando o conjunto filho puder ficar muito grande ou quando os dados relacionados mudarem com frequência.

Considere usar referências nos seguintes casos:

  • Os dados relacionados crescem sem um limite superior claro. Arrays ilimitadas podem causar problemas de desempenho e atingir o limite de tamanho de documento de 16MB do MongoDB.

  • Você precisa fazer query na entidade relacionada por conta própria. Você pode consultar e indexar a coleção secundária diretamente sem digitalizar os documentos principais.

  • Os dados relacionados mudam com frequência e independentemente do pai. Atualizações frequentes de dados incorporados exigem a reescrita de todo o documento pai todas as vezes, o que é ineficiente.

  • O aplicação geralmente não lê dados pai e filho juntos. Ao usar referências, você evita buscar dados filhos de que não precisa.

  • A relacionamento é de muitos para muitos ou complexa.

  • Duplicar os dados criaria muita sobrecarga de atualização.

Para saber mais, consulte Dados de referência na documentação do MongoDB Server .

O exemplo a seguir mostra como armazenar uma referência a uma entidade relacionada:

public class Author
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
}
public class Book
{
public ObjectId Id { get; set; }
public string Title { get; set; } = null!;
// Store reference to Author by storing the Author's Id
public ObjectId AuthorId { get; set; }
}

Para recuperar a entidade relacionada, você deve consultar a coleção referenciada separadamente, como mostrado no exemplo a seguir:

// Query a book and its author
var book = db.Books.FirstOrDefault(b => b.Title == "My Book");
var author = db.Authors.FirstOrDefault(a => a.Id == book!.AuthorId);

Se um documento pai contiver uma array grande, mas seu aplicação geralmente usar somente os itens mais recentes ou acessados com mais frequência, considere o padrão de subconjunto.

No padrão de subconjunto, você mantém os itens acessados com mais frequência no documento principal e move o restante para uma collection separada. Essa abordagem pode reduzir o tamanho do documento e manter mais do seu conjunto de trabalho na RAM, o que pode melhorar o desempenho da consulta.

Esse padrão é útil quando você deseja os benefícios de desempenho da incorporação, mas um histórico incorporado completo faria com que os documentos se tornassem muito grandes ou muito caros para carregar.

Para saber mais sobre as melhores práticas de design de esquema no MongoDB, consulte Melhores práticas para modelagem de dados no MongoDB e Designing your schema na documentação do MongoDB Server .

Para saber mais sobre modelagem de dados no MongoDB, consulte Modelagem de dados na documentação do MongoDB Server .

Para saber mais sobre os tipos de entidades próprias no Entity Framework Core, consulte Tipos de entidades próprias na documentação do Microsoft Entity Framework Core.

Para saber mais sobre os métodos e tipos discutidos neste guia, consulte a seguinte documentação da API da Microsoft:

Voltar

Gravar dados

Nesta página