6

我在線看到的大多數示例都顯示了WinForms/WPF上下文中的對象更改跟蹤。或者如果它在網絡上,則使用連接的對象,因此可以跟蹤對每個對象所做的更改。在N層WCF MVC應用程序中實現對象更改跟蹤

在我的情況下,物體被切斷,一旦他們離開數據層(映射到WCF業務對象,並映射到DTO的MVC應用程序)

當用戶做出對MVC對象的變化(例如,更改1字段屬性),我該如何將視圖中的更改一直髮送到數據庫?

我想要一個審計表,它保存對特定對象所做的更改。我想保存爲對象的&之前之後的值僅適用於我們修改

屬性

我能想到的幾個方法可以做到這一點

1)實現爲每個屬性爲IsDirty標誌MVC圖層中的所有模型(或在JavaScript中?)。將信息一直傳播回服務層,最後傳播到數據層。

2)具有服務層內這種變化的跟蹤機制將是巨大的,但我怎麼會那麼跟蹤「原始」值的修正值已經通過從MVC回來後?

3)數據庫觸發器?但我不確定如何開始。這甚至有可能嗎?

是否有任何已知的對象改變跟蹤的實現在那裏爲一個n層MVC-WCF溶液?審計表的

例子:

Audit table 

Id    Object   Property   OldValue    NewValue 
-------------------------------------------------------------------------------------- 
1    Customer  Name    Bob      Joe 
2    Customer  Age    21      22 
+0

+1 **當用戶對MVC上的對象進行更改(例如,更改1字段屬性)時,如何將該更改從視圖一直髮送到數據庫?**您能解釋一下? –

+0

爲更好的清晰度編輯 –

+0

只需執行映射回ORM類(實體框架?)並調用SaveChanges()。你的問題是什麼? –

回答

3

這個問題可能的解決方案將取決於在什麼樣的變化,你允許在數據庫中,而用戶正在編輯的數據很大一部分。

。換句話說,一旦「離開」的數據庫,是獨有鎖定用戶,也可以其他用戶或進程中同時更新呢?

例如,如果用戶可以獲取數據並在其上停留數小時或數天,但數據庫仍然允許更新數據,那麼您確實想要跟蹤用戶對數據的更改版本當前在數據庫中,而不是用戶對正在查看的數據所做的更改。

,我們處理這種情況的方法是啓動一個事務,讀取整個現有的對象,然後使用反射來比較新舊值,記錄將更改的審計日誌。這在處理嵌套記錄時會變得複雜一些,但非常值得花費時間來實現。

如果,另一方面,沒有其他用戶或進程被允許更改數據,那麼你有一對夫婦,在複雜性,數據存儲改變不同的選項,並影響到現有的數據結構。例如,您可以修改每個類中的每個屬性,以記錄它何時發生變化,並在類中保持這些更改的運行計數(顯然,基類實現在此處有幫助)。但是,根據捕獲用戶更改的時間點(例如每更新一次表單中的字段),這可能會生成大量無用的日誌信息,因爲您可能只想要知道從數據庫角度改變了什麼,而不是從UI角度改變。

您也可以深入克隆該對象並將其傳遞給圖層。然後,當需要確定發生了什麼變化時,您可以再次使用反射。但是,根據業務對象的大小,這種方法可能會導致嚴重的性能損失,因爲完整的副本必須通過網絡移動並保留原始記錄。

您也可以實施與「編輯時允許更新」方法相同的方法。在我看來,這是最乾淨的解決方案,因爲原始數據不必隨編輯的數據一起移動,也不可能篡改原始數據,並且它支持衆多客戶端,而無需支持UI中的更改跟蹤水平。

+0

不,沒有任何內容被鎖定。其他用戶可以編輯相同的數據。 –

+0

好的,那麼我絕對建議您在用於更新記錄的同一交易開始時檢索原始記錄。我們在一個系統中大量使用它,這個系統有成千上萬的用戶通過Web客戶端,移動設備,電子郵件,贏取表格應用程序等提交數據。所有客戶端的數據都通過app層中的一個chokepoint,這是我們按照所述執行審計。 –

+0

那麼你是說,我應該這樣做:例如,用戶想要編輯客戶的數據。 1)從服務(WCF)層檢索客戶數據。 2)更改1個屬性(例如名稱)3)保存時(將數據發送回服務層),再次檢索記錄並執行比較? –

0

有兩個部分你的問題:

  1. 如何做到這一點的MVC:

的常用方法:您更改發送回服務器,控制器處理它們,等等等。在您的用例中,MVC通常工作的方式有所改變,這並不是什麼不尋常的事情。 對於您的用例場景,將更改編碼爲單個更改操作會更好,而不是您需要使用反射來查找用戶所做的更改的修改對象。

  1. 如何做到這一點的數據庫上: 這可能是您想要的問題:
  2. 的所有遠離ORM框架了,生活是因爲它太複雜

第一。

在你應該有以下信息保存操作的最後一步:

  • 的對象和需要改變的字段及其新值。

你必須保持以下信息跟蹤:

  • 什麼最後更改爲您打算在修改數據庫中的對象。

這可以從審覈表中獲得,需要保存在會話(或會話類對象)中。

然後,你需要做以下的交易:

  • 獲取從數據庫中被修改的對象(或多個)的最後一次更改。
  • 如果對象已改變中止,並通知用戶碰撞。
  • 如果未獲取正在更改的字段的當前值。
  • 保存新值。
  • 更新審覈表。

我會使用一個存儲過程來減少這個過程,並且爲數據庫代碼和應用程​​序代碼之間的關係提供更大的分離。

+0

如何跟蹤我打算在數據庫中修改的對象的更改?這是否表明我一直在MVC圖層的ViewModel上實現一個isDirty標誌,並將其一直傳回到數據層? –

+0

1.不需要,您已經擁有審計,如果您需要更改客戶ID = 12,只需在審計跟蹤中記錄該對象最近一次修改的ID。 2.對於您的用例,您需要有一種方法來確定哪些字段已更改。這可能是一個髒標誌,但更有效率的是擁有更改日誌:封裝更改的對象,例如,客戶:10,字段:名稱,值:Bob。這些將直接轉化爲數據庫中的更改。 –

+0

一個問題。你說「首先遠離ORM框架,生活太複雜了。」 - 你如何堅持改變?自己寫sql?或者使用DataTables? – Maarten