Overview
En esta guía, puede aprender a usar el MongoDB Entity Framework Core proveedor para modelar relaciones entre documentos en su base de datos MongoDB. El proveedor de EF Core admite los siguientes tipos de relaciones:
Relaciones embebidas: Subdocumentos embebidos directamente dentro de un documento principal. Este es el enfoque recomendado para relaciones uno a uno y uno a muchos en MongoDB.
Referencias manuales: Un documento que hace referencia a otro documento almacenando su ID en un campo, en lugar de la incrustación del documento como un subdocumento. Este enfoque funciona bien para modelar relaciones de muchos a muchos o cuando necesitas acceder a los documentos de forma independiente.
Tip
Diseña tu esquema para patrones de query
Cuando modeles datos para MongoDB, primero determina las operaciones que tu aplicación ejecuta con mayor frecuencia. Luego, elige una estructura de documento que respalde esas operaciones de manera eficiente. El esquema más eficiente en MongoDB podría no coincidir con el esquema que usarías para una base de datos relacional. En su lugar, considera qué datos se recuperan comúnmente juntos, qué valores cambian frecuentemente y qué relaciones de datos cambian con el tiempo.
Para obtener más información sobre modelado de datos y migración de una base de datos relacional a MongoDB Server, consulta la Tabla de mapeo de SQL a MongoDB y Modelado de datos en MongoDB en la documentación de MongoDB Server.
Relaciones integradas
Para incrustar un subdocumento en un documento principal, especifica el modelo para el documento incrustado como una entidad propietaria. Las relaciones integradas son la forma nativa de MongoDB de modelar relaciones y ofrecen un mejor rendimiento para los documentos a los que accedes frecuentemente juntos.
Cuándo insertar documentos
Uso documentos incrustados cuando los datos relacionados suelen visualizarse en el contexto de su entidad superior y cuando los datos incrustados permanecen razonablemente limitados en tamaño. Esto incluye pequeños conjuntos de valores secundarios, como direcciones, configuraciones o una lista limitada de elementos recientes. Cuando insertas documentos, MongoDB Server puede mejorar el rendimiento al recuperar datos relacionados en una sola operación de base de datos y actualizar datos relacionados atómicamente dentro de un solo documento.
Considera la posibilidad de incrustación de datos en los siguientes casos:
Normalmente, su aplicación lee los datos principales y subordinados juntos. Obtener todo en una sola consulta es más eficiente que hacer llamadas por separado.
Los datos relacionados no crecen sin un límite superior claro. Los datos acotados no provocarán que los documentos crezcan indefinidamente ni que se alcance el límite de tamaño de documento de MongoDB, que es 16MB.
Los datos relacionados no cambian con frecuencia ni de forma independiente del elemento padre. Esto supone menos sobrecarga por reescribir el documento principal.
Nota
Jerarquías anidadas
Cuando actualices cualquier propiedad de una entidad anidada de propiedad, el proveedor de EF Core reescribe todo el documento raíz. Para jerarquías de entidades con tres o más niveles de anidamiento, este costo de guardar se compone, porque un pequeño cambio en lo profundo del árbol desencadena una reescritura completa del documento principal. Si tu modelo utiliza una estructura de anidamiento profundo y tu aplicación realiza operaciones de guardado frecuentes, considera aplanar la jerarquía o reemplazar las entidades de propiedad interna por referencias manuales.
Para obtener más información, consulta Datos integrados en la documentación del MongoDB Server.
Cómo integrar documentos
Puedes designar una entidad de propiedad de las siguientes formas:
[Propiedad] Atributo: Aplica el atributo de anotación de datos
[Owned]a la clase del modelo para el subdocumento. Este enfoque es declarativo y conciso, pero también menos flexible, porque se aplica globalmente a todos los usos del tipo poseído.API fluida: Llama a los métodos
OwnsOne()oOwnsMany()en la configuraciónDbContext. Este enfoque ofrece mayor control y flexibilidad, permitiendo configurar la relación de manera diferente para entidades específicas sin modificar la clase del modelo.
Las siguientes secciones proporcionan ejemplos de estos enfoques para modelar entidades de propiedad única y múltiple.
Una entidad propiedad
Para incrustar un documento único dentro de un documento principal, llama al método OwnsOne() en tu configuración DbContext o aplica el atributo [Owned] a la clase incrustada.
El siguiente ejemplo muestra una entidad Customer que contiene un documento incrustado Address. Selecciona la pestaña [Owned] Attribute o Fluent API para ver la sintaxis correspondiente:
[] 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"); }); } }
Cuando guardas una entidad Customer, MongoDB almacena el Address como un documento incrustado dentro del documento Customer. El siguiente JSON muestra cómo aparece esta relación en MongoDB:
{ "_id": ObjectId("..."), "Name": "John Doe", "Address": { "Street": "123 Main St", "City": "New York", "Country": "USA" } }
Entidades propiedad de múltiples dueños
Para insertar múltiples documentos en un documento principal, llama al método OwnsMany() o aplica el atributo [Owned] a la clase incrustada y define una propiedad de colección.
El siguiente ejemplo muestra una entidad Customer que contiene varios documentos Order incrustados. Selecciona la pestaña [Owned] Attribute o Fluent API para ver la sintaxis correspondiente:
[] 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"); }); } }
Cuando guardas una entidad CustomerWithOrders, MongoDB almacena el Orders como un arreglo de documentos incrustados, como se muestra en el siguiente JSON:
{ "_id": ObjectId("..."), "Name": "Jane Smith", "Orders": [ { "Product": "Laptop", "Quantity": 1 }, { "Product": "Mouse", "Quantity": 2 } ] }
Referencias del manual
Para modelar relaciones entre entidades que no están incrustadas, puedes almacenar referencias manualmente guardando el ID de un documento en un campo de otro documento. Este enfoque requiere que gestiones la relación en el código de tu aplicación.
Cuándo usar referencias
Utiliza referencias cuando consultes regularmente los datos relacionados de forma independiente de sus padres, cuando el conjunto de hijos pueda crecer mucho o cuando los datos relacionados cambien con frecuencia.
Considera usar referencias en los siguientes casos:
Los datos relacionados crecen sin un límite superior claro. Los arreglos ilimitados pueden causar problemas de rendimiento y podrían alcanzar el límite de tamaño de documento de 16MB de MongoDB.
Se debe consultar la entidad relacionada de forma independiente. Puedes query e indexar la colección secundaria directamente sin escanear los documentos principales.
Los datos relacionados cambian con frecuencia e independientemente del padre. Las actualizaciones frecuentes de los datos embebidos requieren reescribir todo el documento principal cada vez, lo cual es ineficiente.
La aplicación normalmente no lee conjuntamente los datos de padre e hijo. Al usar referencias, evitas obtener datos secundarios innecesarios.
La relación es de muchos a muchos o de otra manera compleja.
Duplicar los datos generaría demasiada sobrecarga de actualizar.
Para obtener más información, consulta Datos de referencia en la documentación de MongoDB Server.
Cómo usar referencias
El siguiente ejemplo muestra cómo almacenar una referencia a una entidad 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 la entidad relacionada, debes query la colección referenciada por separado, como se muestra en el siguiente ejemplo:
// 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);
Utiliza el patrón de subconjunto para grandes conjuntos uno a muchos
Si un documento principal contiene un gran arreglo pero tu aplicación generalmente utiliza solo los elementos más recientes o más utilizados, considera el Patrón de subconjunto.
En el patrón de subconjunto, mantenes los elementos que se acceden con mayor frecuencia en el documento principal y move el resto a una colección por separado. Este enfoque puede reducir el tamaño de los documentos y mantener una mayor parte de tu conjunto de trabajo en la RAM, lo que puede mejorar el rendimiento de las query.
Este patrón es útil cuando se desean los beneficios de rendimiento de la incrustación, pero un historial totalmente incrustado haría que los documentos sean demasiado grandes o costosos de cargar.
Información Adicional
Para saber más sobre las mejores prácticas para el diseño de esquemas en MongoDB, consulta Mejores prácticas para el modelado de datos en MongoDB y Diseñando tu esquema en la documentación de MongoDB Server.
Para obtener más información sobre cómo modelar datos en MongoDB, consulta Modelado de datos en la documentación de MongoDB Server.
Para obtener más información sobre los tipos de entidades gobernadas en Entity Framework Core, consulta Tipos de entidades gobernadas en la documentación de Microsoft Entity Framework Core.
Documentación de la API
Para obtener más información sobre los métodos y tipos discutidos en esta guía, consulte la siguiente documentación de la API de Microsoft: