.Net持久化大型列表并以近乎实时的方式保持数据最新

时间:2011-01-24 17:57:42

标签: c# .net sql wpf wcf

好的,坚持下去,因为这里有很多层次,虽然这可能需要一点阅读,但我认为我们所提出的答案对整个社区都非常有用。话虽如此,让我设置问题:

我有一个C#.Net桌面应用程序(Windows Forms,但它可以像我想的那样很容易就是WPF),这是一个销售订单输入和管理系统。我遇到的问题是,我需要在应用程序中使用的最重要的数据列表之一是相当大(大约15k记录,并且正在增长)并且正在发生变化,我想保留列表内存与数据库同步,而不是每2秒或两次轮询数据库。该应用程序也不是单实例,因此所有这些列表都将应用程序需求从数据库引入内存并在每个实例中保留一次。

好的,现在你可以看到困境,让我们看看我们是否可以提出解决方案。

我的想法:

如果我们能够使用.NET 4.0(我可以),我认为在内存中只保留一组数据的答案是使用内存映射文件。虽然它看起来像是一个本垒打,但它的管理要复杂得多,而且可能有些过分。想法?

为了将数据库中的数据加载保持在最低限度,我想到了将各种列表保存到用户PC上某些特殊文件夹中的XML文本文件,然后是一个用于跟踪XML文件的最终XML文件和他们的约会。在应用程序启动时,将执行对DB的单个调用,获取表/列表的列表以及每个表的“上次更新日期”。对于具有相同上次更新日期的每个XML文件,我可以从XML文件加载,而不是查询数据库。对于过时的列表,我可以查询自我拥有的日期以来的更改,然后加载XML文件,然后提交更改。这样,我不得不等待的更多可能是更频繁更新的列表的更改,而不是所有表/列表。好吧,我承认我不是最擅长解释事情,但我认为你应该能够想象它。

至于实时保持最新状态我正在考虑插入和更新触发器(不会发生删除)然后调用SP,这就是我有点模糊的地方,不知何故通过插入/更新信息到应用程序已订阅的WCF服务,并通过WCF回调将更新推送到客户端。现在我认为这应该都可行,但是,例如,这不会导致应用程序的3个实例同时更新内存中的相同更改吗? WCF服务是否能够将更新仅发送到每个客户端PC的一个实例;可以区别吗?

提前感谢您对此的任何想法,意见和建议。我会保留至少48小时“给予”答案,因为我希望每个人都有机会投入2美分,让这个线程对未来更有用......

3 个答案:

答案 0 :(得分:5)

我无法看到将数据库保存在内存中的好处。数据库的要点是数据库。

您必须在应用程序中重现多用户数据库功能。

这似乎是一个没有胜利的主张。把它留给微软。而是创建一个使用sql server的所有功能的n层应用程序。然后,当你有一个可用的测试版时,查找应用程序的部分内容很慢并从那里移动。

答案 1 :(得分:1)

我的程序中有类似的需求,但我的解决方案是构建可以懒惰地加载数据库对象的类(因为它们是需要的),甚至部分用于一些更重要和更大的项目(只是主键和名称开头)。然后每当我正在查看的数据库项目未初始化(只是PK和名称)或仍然为null时,我会转到数据库并急切地加载该对象和其他几个此类对象。

如果你有一个包含15k项目的UI元素,你的程序将几乎无法被人类使用(可能根本不显示任何内容,只需将其保存在列表中)。您应该考虑使用搜索对话框或类似的东西。

答案 2 :(得分:1)

实现这一目标的一种方式,也许是最好的方法是通过记录。

要实现此目的,请将日记帐表与您需要在每个客户端上保持更新的数据库表相关联。该表的主键是时间戳。每当任何客户更新或在(例如)客户表中插入一行时,它还会在日志表中添加一行,指示已添加或更新的客户的主键。

然后,每个客户端都可以通过查询日志表来查找更改列表,查找主键大于或等于客户端上次查询(客户端跟踪)的时间戳的所有行。对customer表的简单连接将获取所有新行和更新的行。然后,客户端将这些行合并到客户表的本地副本中。

你说你不想每2秒或者其他什么来打数据库。三个想法。

首先,它应该足够简单,以便对此进行原型设计并确定是否每2秒访问一次数据库实际上是您需要解决的问题。

第二:每2秒?这对我来说就像一个由魔法信仰驱动的需求而不是实际的商业需求。如果它是由业务需求驱动的,它会让我担心更深层次的问题,例如:假设用户花费超过2秒来执行涉及客户的交易,如果客户行在交易期间发生变化会发生什么?

最后:即使您最终需要实现广播模型,广播的起点也是需要发送给客户端的项目的工作队列。 Journalling是一个很好的起点。

Protip:不要忘记实现从日志表中清除旧条目的日终过程。

相关问题