Overview
在本指南中,您可以学习;了解如何使用MongoDB实体框架核心提供程序对MongoDB 数据库中文档之间的关系进行建模。 EF Core 提供程序支持以下关系类型:
嵌入式关系:直接嵌入父文档中的子文档。对于MongoDB中的一对一和一对多关系,推荐使用这种方法。
手动引用:通过将另一个文档的ID存储在字段中来引用另一个文档,而不是将该文档作为子文档嵌入的文档。此方法非常适合对多对多关系进行建模或需要独立访问权限文档时。
嵌入式关系
要将子文档嵌入到父文档中,请将嵌入式文档的模型指定为自有实体。嵌入式关系是MongoDB对关系进行建模的原生方法,可为经常一起访问权限的文档提供更好的性能。
您可以通过以下方式指定自有实体:
[Owned] 属性:将
[Owned]数据注释属性应用于子文档的模型类。这种方法是声明性的,简洁,但灵活性较低,因为它全局适用于自有类型的所有用法。Fluent API:调用
OwnsOne()OwnsMany()配置中的 或DbContext方法。这种方法提供了更多的控制和灵活性,允许您为特定实体以不同的方式配置关系,而无需修改模型类。
以下部分举例说明了对单个和多个自有实体进行建模的方法。
一个拥有的实体
要将单个文档嵌入到父文档中,请调用 DbContext 配置中的 OwnsOne() 方法或应用[Owned] 属性应用于嵌入式类。
以下示例显示了一个包含嵌入式 Address文档的Customer 实体。选择 [Owned] Attribute 或 Fluent API标签页,查看相应的语法:
[] 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"); }); } }
保存 Customer 实体时, MongoDB会将 Address 存储为 Customer文档中的嵌入式文档。以下JSON显示了此关系在MongoDB中的显示方式:
{ "_id": ObjectId("..."), "Name": "John Doe", "Address": { "Street": "123 Main St", "City": "New York", "Country": "USA" } }
多个拥有实体
要将多个文档嵌入到父文档中,请调用 OwnsMany() 方法或应用[Owned] 属性应用于嵌入式类并定义一个集合属性。
以下示例显示了一个包含多个嵌入式 Order 文档的 Customer 实体。选择 [Owned] Attribute 或 Fluent API标签页,查看相应的语法:
[] 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"); }); } }
保存 CustomerWithOrders 实体时, MongoDB会将 Orders 存储为嵌入式文档大量,如以下JSON所示:
{ "_id": ObjectId("..."), "Name": "Jane Smith", "Orders": [ { "Product": "Laptop", "Quantity": 1 }, { "Product": "Mouse", "Quantity": 2 } ] }
手动引用
要对非嵌入式实体之间的关系进行建模,您可以通过将一个文档的ID保存在另一个文档的字段中来手动存储引用。这种方法要求您在应用程序代码中管理这种关系。
以下示例展示了如何存储对相关实体的引用:
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; } }
要检索相关实体,必须单独查询引用的集合,如以下示例所示:
// 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);
更多信息
要学习;了解有关在MongoDB中进行数据建模的更多信息,请参阅MongoDB Server文档中的 数据建模。
要学习;了解有关 Entity Framework Core 中自有实体类型的更多信息,请参阅Microsoft Entity Framework Core 文档中的自有实体类型。
API 文档
要学习;了解有关本指南中讨论的方法和类型的更多信息,请参阅以下Microsoft API文档: