2008-12-10 54 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