2011-10-13 23 views
3

我已經開始在RavenDB的一個示例中學習NoSQL。我已經開始與一個簡單的模型,假設我們有用戶創建的主題:如何同步nosql db中的更改(ravendb)

public class Topic 
{ 
    public string Id { get; protected set; } 
    public string Title { get; set; } 
    public string Text { get; set; } 

    public DenormalizedUser User { get; set; } 
} 

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

public class User 
{ 
    public string Id { get; protected set; } 
    public string Name { get; set; } 
    public DateTime Birthdate { get; set; } 

    //some other fields 
} 

我們不需要用於顯示Topic整個User,因此我將非規格化到DenormalizedUser,含IdName

所以,這裏的問題:

1)這種方法糾正的NoSQL?

2)如何處理User更改Name的情況?我是否需要手動更新非規格化類中的所有Name字段?

+0

不知道的問題1. 2,是的,你將不得不更新字段爲「DenormalizedUser」「名稱」太多,因爲字符串,對於所有意圖和目的,是通過值,不處理參考。我不僅僅明白爲什麼你不能僅僅使用'User' - 'DenormalizedUser'來表示無意義和冗餘的數據。爲了清晰和語法,編輯(多次)。我需要更多咖啡._ –

回答

3

Shaddix你可以使用Raven DB Include功能從你的話題中使用UserId加載用戶。

var topic = _session.Load<Topic>(topicId) 
        .Customize(x => x.Include<Topic>(y => y.UserId)); 

var user = _session.Load<User>(topic.UserId); 

負載爲主題將'預加載'用戶和兩個負載將只會導致一個GET請求。 (由於我的聲望,我無法直接回復您對Ayende的回覆)。

您還可以使用替代(可能更清晰).Include()函數沒有Customize()。

http://docs.ravendb.net/consumer/querying/handling-document-relationships.html

+0

謝謝,這是要走的路,但如果我查詢主題列表,並且我不僅在'Topic'內有'User'作爲參考,與NH相比,語法變得過於複雜(有關dlang的評論的示例).. – Shaddix

+0

上面有一個查詢文檔關係鏈接的例子。 'VAR主題= session.Query ().Customize(X => x.Include (T => t.UserId))ToList();' 然後,您可以將每個添加到您的視圖模型: 'foreach(var topic in topics) { var user = session.Load (topic.UserId); // viewmodel list.Add(new TopicViewModel {....}); }' 它不像NH那樣'乾淨',但我認爲使用Raven的時間和頭痛失去了勝過。如果需要的話,你也可以將它捆綁到一些擴展方法來清理你的控制器/服務。 – Matt

+0

這是考慮延伸方法的好處,是的。感謝您提供的鏈接,它真的描述了所有可能的方法。對於所有好的和「本地」的c#api都沒有這個可惜,我會去看看MongoDB的世界,但是我認爲他們的API在其他方面會變得更糟。 – Shaddix

3

shaddix, 你不需要進行非規範化,就可以抱到ID的引用,然後包括當你從服務器

+0

謝謝,Ayende,但是如果我只有UserId,我如何訪問'topic.User.Name'?當然,我可以做'_session.Query ().Where(x => x.Id == topic.UserId)',但是它比使用NHibernate的RDBMS方便得多,我可以參考' 「Topic」內部的用戶,還是有其他方法? – Shaddix

2

1)加載是,這種方法工作得很好,結果是,你只需要加載主題文檔,當你想顯示它的用戶名稱。然而,正如Ayende所說,性能將幾乎相同,如果您沒有對用戶進行非規範化處理,並在需要時將其包含在內。如果您不擔心多服務器部署,我建議您採用這種方法。 2)如果你真的想要非規範化用戶,那麼你可以簡單地使用基於集合的操作來更新引用這個用戶的所有主題。看看這個:http://ravendb.net/faq/denormalized-updates

+0

我很滿意''包括',特別是因爲它仍然只有一個DB-hit,我只是擔心在這種情況下的易用性。假設我希望獲得一個包含主題和用戶列表的ViewModel,那麼如何使用Include來做到這一點? '_session.Query ().Include(x => x.UserId).Select(topic => new {Topic = topic,User = _session.Query ().Where(u => u.Id == topic。 UserId)})'?在NHibernate中,它只是:'_session.Query ().Fetch(x => x.User)'參考'Topic'內的'User',它看起來更乾淨,希望能找到類似於nosql ... – Shaddix

+0

順便說一句,感謝非規範化更新鏈接,真的很有用 – Shaddix

+0

你的代碼示例如何使用'.Include'真的很好,是的,它的工作方式。我使用NHibernate多年,我同意,使用'.Fetch'並直接引用用戶更清潔。如果有人正確使用RavenDB,你會在他的數據模型中看到它。 –