2013-02-06 33 views
1

存储的ID列表的父文档中如果我有一个可以有多个孩子,如Store可以有多个Product个父文档有存储在StoreProduct.Id一个列表中的任何更简单的方法文件?更简单的方法使用RavenDB

当前我只是先存储Product对象,然后遍历它们以获得Store.ProductIds属性的Product.Id

商店

​​3210

产品

class Product 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
} 

当前工作保存方法

var store = new Store() 
{ 
    Name = "Walmart", 
    Products = new List<Product> 
        { 
         new Product {Name = "Ball"}, 
         new Product {Name = "Bat"} 
        } 
}; 

using (var session = DocumentStore.OpenSession()) 
{ 
    foreach (var product in store.Products) 
    { 
     session.Store(product); 
    } 

    session.SaveChanges(); 

    var list = new List<string>(); 

    foreach (var product in store.Products) 
    { 
     list.Add(product.Id); 
    } 

    store.ProductIds = list; 

    session.Store(store); 
    session.SaveChanges(); 
} 

回答

2

要回答您的具体问题 - 有两两件事你可以用代码简化:

  • 您可以在第一时间清除session.SaveChanges();产品ID将被创建的时候,你的产品叫.Store()

  • 您可以收集的产品ID与某些LINQ到其倒闭一条线:

    store.ProductIds = store.Products.Select(x=> x.Id).ToList();

你仍然具有相同的一般方法,但 - 它只是简化了代码一点。

此方法将工作,但要意识到您只是为了方便将商品放入商店。 [JsonIgnore]在这里没问题,但它只能帮助序列化 - 而不是反序列化。换句话说,加载商店时,只会填充ProductIds列表。您将不得不单独加载它们(可能使用.Include()

就我个人而言,我会将Products列表从Store对象中完全取出。像Entity Framework和NHibernate这样的其他关系产品为此使用虚拟成员和代理类,但它在RavenDB中意义不大。您的班级的消费者不会知道该物业被忽略,因此他们可能会误解其用途。当我看到Products属性时,我的期望是每个Product都完全嵌入到文档中 - 在这种情况下,您不需要单独的ProductIds列表。让他们两个都被忽视只会造成混乱。

另一个反对你提议的设计的观点是,它暗含地使每个商店中的每个产品都是独一无二的。这是因为您正在与商店创建产品,然后分别添加每个产品。如果确实是所有产品都是独特的(不仅仅是“球”,而是“特定球”),那么您可以嵌入产品而不需要[JsonIgnore]ProductIds列表,并且不需要Product作为单独的文件存在。在更可能的情况是产品不是唯一的(多个商店可以卖蝙蝠和球),那么你有两个选择:

class Store 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public IList<string> ProductIds { get; set; } 
} 

class Store 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public IList<Product> Products { get; set; } 
} 

Product仍然是它自己的文件有两种情况 - 第二个情况是用作denormalized reference,因此您可以在不加载产品的情况下获取产品名称。这是可以接受的,但是如果产品名称可以改变,那么你有很多补丁可以做。

对不起,如果没有干净的“这样做”的答案。 Raven有很多选择,有时候这种或那种方式会更好,这取决于你使用它的所有不同方式。我个人 - 我只是保留ProductIds列表。您始终可以使用index the related document来提取产品名称以进行查询。

+0

这很有道理,我将不得不再探索一下,看看最适合我的场景的是什么。我将产品分成单独集合的原因仅仅是因为我听到了[Herding Code](http://herdingcode.com/?p=493)podcast的建议,其中一位开发人员[ MarkedUp](https://markedup.com/)建议当内部对象的数量变大时不要使用内部对象集合,我忘记了确切的数字。感谢设计咨询! –

+0

同意。事实上,您可能想要反转关系并在每个产品上存储StoreIds列表。或者你可能需要一个单独的'Inventory'对象来绑定一个StoreId,ProductId和一个Quantity。 –

+0

好点。我可能会继续前进,移动关系并将StoreIds存储在每个产品上。 –