2010-04-27 149 views
2

問題 - 如何使用數據庫保存/保持同步對象的jn內存圖的最佳實踐方法是什麼?如何使用數據庫保存/保持對象的內存圖形對象?

背景:

也就是說說我有類節點和關係,並且應用程序建立使用這些類的相關對象的圖形。可能有1000個節點之間存在各種關係。應用程序需要查詢結構,因此內存中的方法對性能毫無疑問是有好處的(例如遍歷節點X的圖來查找根父節點)

該圖確實需要持久化到帶有表的數據庫中節點和關係。

因此,如何使用數據庫保存/保持同步jn內存對象圖形,最佳實踐方法是什麼?

理想要求將包括:

  • 積聚變化的內存中,然後「拯救」之後(強制性)
  • 保存時,在正確的順序,以避免撞上任何數據庫約束將更新應用到數據庫(強制)
  • 保持持久性機制與模型分離,以便於在需要時更改持久層,例如不只是包裝的ADO.net的DataRow在節點和關係類(希望)
  • 機制做樂觀鎖(希望)

或者是這一切對一個很小的應用程序只是不值得的開銷它和我應該每次都打到數據庫的一切? (假設響應時間是可以接受的)[仍然希望避免如果沒有太多的額外開銷,以保持稍微可擴展的重新性能]

回答

0

簡而言之,您仍然可以保持對象的圖形(鏈接對象的集合)在內存中,並在發生數據庫時將更改寫入數據庫。如果這需要太長時間,可以將更改放到消息隊列中(但這可能是矯枉過正),或執行更新並插入到單獨的線程中。

+0

有沒有明顯的開箱即用的方法,然後詹姆斯與.net?比如ado.net或者linq-to-sql或者企業框架沒有提供一個簡單的解決方法,或者一個模式來解決? – Greg 2010-04-27 23:51:13

1

我在實體框架4中使用自我跟蹤實體。實體加載到內存後,必須在每個實體上調用StartTracking()。然後你可以在內存中修改你的實體圖,而不需要任何數據庫操作。完成修改後,您可以調用上下文擴展方法「ApplyChanges(rootOfEntityGraph)」和SaveChanges()。所以你的修改是持久的。現在您必須再次開始對圖中每個實體進行跟蹤。兩個提示/想法我使用的時刻:

1)開頭的每個實體調用StartTracking()

我使用的接口IWorkspace到抽象的ObjectContext(簡化了測試 - >見sourceforge的OpenSource實現bbv.DomainDrivenDesign)。他們也使用QueryableContext。所以我創建了一個更具體的Workspace和QueryableContext實現,並用自己的IEnumerable實現攔截加載過程。當工作空間的使用者執行使用CreateQuery()獲得的查詢時,我的攔截IEnumerable對象在上下文的ChangeTracker上註冊一個事件處理器。在這個事件處理程序中,我爲每個加載到上下文中的實體調用StartTracking()(如果使用NoTrakcing加載對象,則不起作用,因爲在這種情況下,對象不會添加到上下文中,並且事件處理程序不會被辭退了)。在自制Iterator中枚舉之後,ObjectStateManager上的事件處理程序將被註銷。

2)調用ApplyChanges後StartTracking()()/調用SaveChanges()

在工作區中實施,請問上下文的ObjectStateManager對修改後的實體,即:

VAR addedEntities = this.context .ObjectStateManager.GetObjectStateEntries(EntityState.Added); - >類似於修改實體

將它們轉換爲IObjectWithChangeTracker並在實體本身上調用AcceptChanges()方法。這會再次啓動對象的更改跟蹤器。

對於我的項目,我有和你一樣的要點。我用EF 3.5玩過,並沒有找到令人滿意的解決方案。但EF 4中自我追蹤實體的新能力似乎符合我的要求(就我探索的功能性而言)。

如果你有興趣,我會給你我的「秒殺」項目。

是否有其他解決方案?我的項目是一個服務器應用程序,它將對象保存在內存中用於快速操作,而修改也應該保持不變(不會往返DB)。在代碼中的某些點,對象圖被標記爲已刪除/終止,並從內存容器中刪除。通過上面解釋的解決方案,我可以重複使用EF生成的模型,而無需再次編寫和包裝所有對象。生成的自我跟蹤實體代碼來自T4模板,可以很容易地進行調整。

非常感謝其他想法/批評

+0

這聽起來很有趣,而且 - 這是EF的一個流行/很好用的部分嗎?這個EF功能的實現是否可靠? (就像它剛剛發佈的一個新功能,或者從開始就已經在EF中) – Greg 2010-05-04 21:00:21