2008-12-10 50 views
3

我试图创建一个LINQ to SQL类,它代表了它自己的“最新”版本。LINQ to SQL对象版本化

现在,这个实体表示的表有一个自动递增的ID,我想我会为主键添加一个版本号。我从来没有做过这样的事情,所以我不知道如何继续。我希望能够将对象版本的想法从任何使用它的人抽象出来。换句话说,您拥有一个代表最新版本的实体实例,并且每当提交任何更改时,对象的新副本都将以增加的版本号存储。

我应该如何继续?

回答

5

如果您可以避免保留历史记录,请执行。这是一个痛苦。

如果完整的历史记录是不可避免的(受监管的财务和医疗数据等),请考虑添加历史记录表。使用触发器将'版本'放入历史记录表格中。这样,您不需要依赖应用程序来确保记录版本 - 无论源是何种类型,都会捕获所有插入/更新/删除。

如果您的应用需要与历史数据进行交互,请确保它是只读的。如果有人可以简单地改变它们,就没有意义捕捉交易历史。

如果您关心的是并发更新,请考虑使用记录更改时间戳。当用户A和用户B在中午查看记录时,他们获取记录的时间戳。当用户A更新记录时,她的时间戳记与记录相匹配,所以更新过程以及时间戳记也被更新。当用户B五分钟后更新记录时,他的时间戳记与记录不匹配,所以他被警告记录自从他上次查看以来已更改。也许它会自动重新加载...

无论你决定,我会避免混合当前和历史数据。每评论


触发源:

的关键在于审计触发器是virtual tables 'inserted' and 'deleted'。这些表包含由INSERT,UPDATE或DELETE影响的行。您可以使用它们来审核更改。例如:

CREATE TRIGGER tr_TheTrigger 
ON [YourTable] 
FOR INSERT, UPDATE, DELETE 
AS 
    IF EXISTS(SELECT * FROM inserted) 
    BEGIN 
     --this is an insert or update 
     --your actual action will vary but something like this 
     INSERT INTO [YourTable_Audit] 
      SELECT * FROM inserted 
    END 
    IF EXISTS(SELECT * FROM deleted) 
    BEGIN 
     --this is a delete, mark [YourTable_Audit] as required 
    END 
GO 
0

继续下去的最好方法就是停下来认真反思一下你的方法。

如果您打算保留不同版本的“对象”,那么最好将它序列化为xml格式,并将其存储在具有版本号字段的XML列中。

当试图在SQL Server中维护版本化的数据时,需要认真考虑围绕应用程序维护。根据注释

UPDATE:

这些注意事项包括:无法删除字段或更改字段的数据类型在将来的“版本”。新字段必须为空,或者至少在数据库中为其存储默认值。因此,您将无法将其用于唯一索引或作为主键的一部分。

总之,应用程序可以做的唯一事情就是展开。只要前面的代码层可以忽略扩展。

这是桌面软件制造商多年来一直困扰着的向后兼容的典型问题。这是你可能想要远离它的原因。

+0

您能详细说明一些这些注意事项吗? – 2008-12-10 15:50:10

+1

是的,我意识到这些问题。我真心希望远离这一点,但我们必须出于法律原因这样做。如果他们只需要以某种“哑巴”格式存档数据,我只会将其存储为一个巨大的字符串或其他东西,但应用程序需要与历史记录进行交互。 – 2008-12-11 05:06:30