共用方式為


使用異動來更新模型

異動可確保會對存放區所進行的變更視為群組。 可以認可分組的變更或將其回復為單一單位。

每當程式碼修改、新增或刪除 Visual Studio Visualization 和 Modeling SDK 之存放區中的任何元素時,都必須在異動內執行此動作。 變更發生時,必須有與存放區相關聯的 Transaction 作用中執行個體。 這適用於所有模型元素、關聯性、圖形、圖表及其屬性。

異動機制可協助您避免狀態不一致。 如果在異動期間發生錯誤,則會回復所有變更。 如果使用者執行了 Undo 命令,則會將每個最近的異動視為單一步驟。 使用者無法復原最近變更的部分,除非您明確地將它們放在個別的異動中。

開啟異動

管理異動最方便的方法,是將 using 陳述式括在 try...catch 陳述式中:

Store store; ...
try
{
  using (Transaction transaction =
    store.TransactionManager.BeginTransaction("update model"))
    // Outermost transaction must always have a name.
  {
    // Make several changes in Store:
    Person p = new Person(store);
    p.FamilyTreeModel = familyTree;
    p.Name = "Edward VI";
    // end of changes to Store

    transaction.Commit(); // Don't forget this!
  } // transaction disposed here
}
catch (Exception ex)
{
  // If an exception occurs, the Store will be
  // rolled back to its previous state.
}

如果防止最終 Commit() 的例外狀況在變更期間發生,存放區會重設為其先前的狀態。 這可協助您確定錯誤不會讓模型處於不一致的狀態。

您可以在一個異動內進行任何數量的變更。 可以在作用中的異動內開啟新的異動。 巢狀異動必須在包含異動結束之前加以認可或回復。 如需詳細資訊,請參閱 TransactionDepth 屬性的範例。

若要進行永久變更,您應該先Commit異動,然後再進行處置。 如果異動內沒有攔截到例外狀況的發生,則會將存放區重設回變更前的狀態。

復原交易

若要確保存放區維持處於或還原至異動之前的狀態,您可以使用下列任一策略:

  1. 引發未在異動範圍內攔截到的例外狀況。

  2. 明確地回復異動:

    this.Store.TransactionManager.CurrentTransaction.Rollback();
    

異動不會影響非存放區物件

異動只會控管存放區的狀態。 它們無法復原對外部項目 (例如使用 DSL 定義之外一般類型宣告的檔案、資料庫或物件) 所進行的部分變更。

如果例外狀況可能導致此類變更與存放區不一致,您應該處理例外處理常式中的該種可能性。 若要確保外部資源與存放區物件保持同步,其中一個方法是使用事件處理常式將每個外部物件與存放區內元素結合在一起。 如需詳細資訊,請參閱事件處理常式傳播在模型外的變更 (部分機器翻譯)。

規則會在異動結束時引發

在異動結束時且對異動進行處置之前,會引發連結至存放區中元素的規則。 每個規則都是套用至已變更之模型元素的方法。 例如有些「修正」規則,可在 [圖形] 的模型元素變更時更新 [圖形] 的狀態,進而在建立模型元素時建立 [圖形]。 並沒有指定的引發順序。 由規則所做的變更可能會引發另一個規則。

您可以定義自己的規則。 如需規則的詳細資訊,請參閱 回應和傳播變更 (部分機器翻譯)。

規則不會在復原、重做或還原命令之後引發。

交易內容

每個異動都有一個字典,您可以在其中儲存任何想要的資訊:

store.TransactionManager

.CurrentTransaction.TopLevelTransaction

.Context.Add(aKey, aValue);

這對於在規則之間傳送資訊尤其實用。

異動狀態

在某些情況下,如果變更是由復原或重做異動所造成,您需要避免傳播變更。 例如,如果您撰寫可更新存放區中另一個值的屬性值處理常式,就可能會發生這種情況。 由於復原作業會將存放區中的所有值重設為先前的狀態,因此不需要計算更新的值。 使用這段程式碼:

if (!this.Store.InUndoRedoOrRollback) {...}

最初從檔案載入存放區時規則可能會引發。 若要避免回應這些變更,請使用:

if (!this.Store.InSerializationTransaction) {...}