如何使用数据库保存/保持对象的内存图形对象?

问题描述:

问题 - 如何使用数据库保存/保持同步对象的jn内存图的最佳实践方法是什么?如何使用数据库保存/保持对象的内存图形对象?

背景:

也就是说说我有类节点和关系,并且应用程序建立使用这些类的相关对象的图形。可能有1000个节点之间存在各种关系。应用程序需要查询结构,因此内存中的方法对性能毫无疑问是有好处的(例如遍历节点X的图来查找根父节点)

该图确实需要持久化到带有表的数据库中节点和关系。

因此,如何使用数据库保存/保持同步jn内存对象图形,最佳实践方法是什么?

理想要求将包括:

  • 积聚变化的内存中,然后“拯救”之后(强制性)
  • 保存时,在正确的顺序,以避免撞上任何数据库约束将更新应用到数据库(强制)
  • 保持持久性机制与模型分离,以便于在需要时更改持久层,例如不只是包装的ADO.net的DataRow在节点和关系类(希望)
  • 机制做乐观锁(希望)

或者是这一切对一个很小的应用程序只是不值得的开销它和我应该每次都打到数据库的一切? (假设响应时间是可以接受的)[仍然希望避免如果没有太多的额外开销,以保持稍微可扩展的重新性能]

简而言之,您仍然可以保持对象的图形(链接对象的集合)在内存中,并在发生数据库时将更改写入数据库。如果这需要太长时间,可以将更改放到消息队列中(但这可能是矫枉过正),或执行更新并插入到单独的线程中。

+0

有没有明显的开箱即用的方法,然后詹姆斯与.net?比如ado.net或者linq-to-sql或者企业框架没有提供一个简单的解决方法,或者一个模式来解决? – Greg 2010-04-27 23:51:13

我在实体框架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