LINQ to SQL对象版本控制

时间:2008-12-10 15:24:11

标签: sql-server vb.net linq-to-sql

我正在尝试创建一个LINQ to SQL类,它代表了自身的“最新”版本。

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

我该如何处理?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

最好的方法是停止并认真重新思考你的方法。

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

在尝试维护sql server中的版本化数据时,需要考虑应用程序维护。

每条评论更新:

这些考虑因素包括:在将来的“版本”中无法删除字段或更改字段的数据类型。新字段必须是可空的,或者至少具有存储在DB中的默认值。因此,您将无法在唯一索引中或作为主键的一部分使用它们。

简而言之,您的应用程序唯一可以做的就是扩展。前提是前一层代码可以忽略扩展。

这是桌面软件制造商多年来一直在努力解决的经典倒退兼容性问题。这也是你可能想远离它的原因。