2013-02-06 65 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存儲在每個產品上。 –