如何在不同的mongodb集合中存储嵌套对象?

发布于 2024-09-15 13:17:46 字数 1170 浏览 1 评论 0原文

我需要存储此类的一些对象:

public class Category{
    public ObjectId Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public List<Product> Products {get;set;}
}

public class Product{
    public ObjectId Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public decimal Price {get;set;}
}

当我使用 NoRM 并存储类别对象时 mongo.GetCollection().Insert(类别); 我可以在 mongo shell 中看到:

db.Category.find()
{ "_id" : ObjectId("82bbbf0179eae0141d020000"), "Name" : "Test products", "Descr
iption" : "This is test category", "Products" : [
        {
                "_id" : ObjectId("81bbbf0179eae0141d000000"),
                "Name" : "Product1",
                "Description" : "first product",
                "Price" : {

                }
        },
        {
                "_id" : ObjectId("82bbbf0179eae0141d010000"),
                "Name" : "Product2",
                "Description" : "second product",
                "Price" : {

                }
        }
] }

我可以将类别和产品对象存储在不同的集合中,并且仅在类别记录中引用产品,而不更改类的代码吗? (就像 NHibernate 那样)

I need to store some objects of this classes:

public class Category{
    public ObjectId Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public List<Product> Products {get;set;}
}

public class Product{
    public ObjectId Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public decimal Price {get;set;}
}

When I use NoRM and store a Category object with
mongo.GetCollection().Insert(Category);
I can see in mongo shell:

db.Category.find()
{ "_id" : ObjectId("82bbbf0179eae0141d020000"), "Name" : "Test products", "Descr
iption" : "This is test category", "Products" : [
        {
                "_id" : ObjectId("81bbbf0179eae0141d000000"),
                "Name" : "Product1",
                "Description" : "first product",
                "Price" : {

                }
        },
        {
                "_id" : ObjectId("82bbbf0179eae0141d010000"),
                "Name" : "Product2",
                "Description" : "second product",
                "Price" : {

                }
        }
] }

Can I store Category and Product objects in different collections and have just a reference to a Product within a Category record without changing the code of classes? (The way like NHibernate does)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌生 2024-09-22 13:17:46

不,你不能。至少不会自动发生。

SQL 数据库最适合跨多个表存储规范化数据。表之间的关系由外键关系定义。 NHibernate 使用这些外键关系将对象映射到多个表。

MongoDB 适合存储文档。这些文档通常是数据的非规范化表示。这个想法是将相关数据存储在单个文档而不是多个表中。由于这种理念,MongoDB 不需要外键概念或连接集合的能力。

理论上NoRM将来可以支持这样的功能,但这违背了文档数据库的精神。因此它不太可能得到支持。

手动解决方案

您可以通过应用 MongoIgnore 属性来告诉 NoRM 在保存类别时跳过 Products 属性。然后将产品手动存储在单独的集合中,并附上对该类别的“引用”。您可以使用自定义集合自动跟踪产品类别。代码如下所示:

public class ProductCollection : Collection<Product>
{
  private Category owner;

  public ProductCollection(Category owner)
  {
    // Remember who 'owns' the products in this collection.
    this.owner = owner;
  }

  protected override void InsertItem(int index, Product item)
  {
    // Tell the product to which category it belongs.
    item.CategoryId = this.owner.Id;

    base.InsertItem(index, item);
  }

  // Override other methods using the same pattern.
}

public class Category
{
  public Category()
  {
    this.Id = ObjectId.NewObjectId();
    this.Products = new ProductCollection(this);
  }

  public ObjectId Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }

  [MongoIgnore]
  public ProductCollection Products { get; private set; }
}

public class Product
{
  public ObjectId Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
  public decimal Price { get; set; }
  public ObjectId CategoryId { get; set; }
}

现在您可以将类别存储在一个集合中,将产品存储在另一个集合中。 CategoryId 属性将指示产品所属的类别。

No, you can't. At least not automatically.

SQL databases are best for storing normalized data across multiple tables. The relations between tables are defined by foreign key relations. NHibernate uses these foreign key relations to map objects to multiple tables.

MongoDB is geared towards storing documents. These documents are usually a denormalized representation of the data. The idea is to store related data in a single document instead of multiple tables. As a result of this philosophy MongoDB has no need for foreign key concepts or the ability to join collections.

In theory NoRM could support such functionality in the future, but this would go against the spirit of document databases. So it's unlikely that it will ever be supported.

Manual Solution

You can tell NoRM to skip the Products property when saving a category by applying the MongoIgnore attribute. Then store the products manually in a separate collection, together with a 'reference' to the category. You can auto-track the category for products by using a custom collection. The code would look something like this:

public class ProductCollection : Collection<Product>
{
  private Category owner;

  public ProductCollection(Category owner)
  {
    // Remember who 'owns' the products in this collection.
    this.owner = owner;
  }

  protected override void InsertItem(int index, Product item)
  {
    // Tell the product to which category it belongs.
    item.CategoryId = this.owner.Id;

    base.InsertItem(index, item);
  }

  // Override other methods using the same pattern.
}

public class Category
{
  public Category()
  {
    this.Id = ObjectId.NewObjectId();
    this.Products = new ProductCollection(this);
  }

  public ObjectId Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }

  [MongoIgnore]
  public ProductCollection Products { get; private set; }
}

public class Product
{
  public ObjectId Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
  public decimal Price { get; set; }
  public ObjectId CategoryId { get; set; }
}

Now you can store categories in one collection and the products in another collection. The CategoryId property will indicate the category to which a product belongs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文