如何在不同的mongodb集合中存储嵌套对象?
我需要存储此类的一些对象:如何在不同的mongodb集合中存储嵌套对象?,mongodb,norm,Mongodb,Norm,我需要存储此类的一些对象: 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;
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;}
}
我是否可以将类别和产品对象存储在不同的集合中,并且在类别记录中仅引用一个产品而不更改类代码?(就像NHibernate那样)不,你不能。至少不是自动的 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; }
}
公共类ProductCollection:集合
{
私有类别所有者;
公共产品集合(类别所有者)
{
//记住谁是本系列产品的“所有者”。
this.owner=所有者;
}
受保护的覆盖无效插入项(整数索引,产品项)
{
//告诉产品它属于哪个类别。
item.CategoryId=this.owner.Id;
基本插入项(索引,项目);
}
//使用相同的模式重写其他方法。
}
公共类类别
{
公共类别()
{
this.Id=ObjectId.NewObjectId();
this.Products=新产品集合(this);
}
公共对象Id{get;set;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
[蒙哥尼诺]
公共产品集合产品{get;private set;}
}
公共类产品
{
公共对象Id{get;set;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
公共十进制价格{get;set;}
public ObjectId CategoryId{get;set;}
}
现在,您可以将类别存储在一个集合中,将产品存储在另一个集合中。
CategoryId
属性将指示产品所属的类别。产品和类别之间存在一对多关系。我建议您将引用存储在多实体中,就像存储在SQL数据库中一样。因此,产品是指一个类别,而不是相反。其优点是,当您将产品移动到其他类别时,只需更新产品中的引用即可。在您的设计中,您必须将产品从旧类别中删除并添加到新类别中。如果你的例子只是为了说明问题,请忽略我的评论:)谢谢你的完整答案。我将在我的项目中使用此解决方案。
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; }
}