/// <summary> /// Unloads all the data and relation end-points from the <see cref="ClientTransaction"/> hierarchy indicated by the given /// <paramref name="clientTransaction"/>. This operation always succeeds (unless it is canceled by an exception thrown from a /// <see cref="IClientTransactionListener.ObjectsUnloading"/> or <see cref="DomainObject.OnUnloading"/> notification method). /// </summary> /// <param name="clientTransaction">The <see cref="ClientTransaction"/> to unload the data from. The unload operation always affects the whole transaction /// hierarchy.</param> /// <exception cref="ArgumentNullException">One of the arguments passed to this method is <see langword="null"/>.</exception> /// <remarks> /// <para> /// The unload operation is atomic over the transaction hierarchy. If the operation is canceled in any of the transactions, /// it will not unload any data. /// </para> /// <para> /// The effect of this operation is similar to that of a <see cref="ClientTransaction.Rollback"/> followed by calling /// <see cref="UnloadVirtualEndPoint"/> and <see cref="UnloadData"/> for every piece of data in the <see cref="ClientTransaction"/>, although /// the operation won't raise any Rollback-related events. /// </para> /// <para> /// When the operation completes, the state of previously <see cref="StateType.Changed"/>, <see cref="StateType.Deleted"/>, and /// <see cref="StateType.Unchanged"/> objects becomes <see cref="StateType.NotLoadedYet"/>. The state of <see cref="StateType.New"/> objects /// becomes <see cref="StateType.Invalid"/> (this state is propagated over within the whole transaction hierarchy). /// The state of <see cref="StateType.Invalid"/> and <see cref="StateType.NotLoadedYet"/> objects stays the same. /// </para> /// <para> /// When the operation completes, all virtual relation end-points will no longer be complete, and they will be reloaded on access. All changes, /// including <see cref="DomainObjectCollection"/> references set into relation properties, will be rolled back. /// </para> /// </remarks> public static void UnloadAll(ClientTransaction clientTransaction) { ArgumentUtility.CheckNotNull("clientTransaction", clientTransaction); Func <ClientTransaction, IDataManagementCommand> commandFactory = tx => tx.DataManager.CreateUnloadAllCommand(); var executor = new TransactionHierarchyCommandExecutor(commandFactory); executor.ExecuteCommandForTransactionHierarchy(clientTransaction); }
/// <summary> /// Resurrects the invalid <see cref="DomainObject"/> with the given <paramref name="objectID"/> in the hierarchy of the given /// <paramref name="clientTransaction"/>, returning a value indicating if the resurrection was successful. /// </summary> /// <param name="clientTransaction">A <see cref="ClientTransaction"/> identifying the hierarchy in which to resurrect the object. The object /// is resurrected in all transactions of the hierarchy.</param> /// <param name="objectID">The <see cref="ObjectID"/> of the object to resurrect.</param> /// <returns><see langword="true" /> if the resurrection succeeded, <see langword="false" /> otherwise. Resurrection does not succeed if /// the <see cref="DomainObject"/> identified by <paramref name="objectID"/> is not invalid in at /// least one <see cref="ClientTransaction"/> of the transaction hierarchy identified by <paramref name="clientTransaction"/>. /// </returns> public static bool TryResurrectInvalidObject(ClientTransaction clientTransaction, ObjectID objectID) { ArgumentUtility.CheckNotNull("clientTransaction", clientTransaction); ArgumentUtility.CheckNotNull("objectID", objectID); var executor = new TransactionHierarchyCommandExecutor(tx => CreateMarkNotInvalidCommand(tx, objectID)); return(executor.TryExecuteCommandForTransactionHierarchy(clientTransaction)); }
/// <summary> /// Unloads the data held by the given <see cref="ClientTransaction"/> for the <see cref="DomainObject"/> with the specified /// <paramref name="objectID"/>, returning a value indicating whether the unload operation succeeded. The <see cref="DomainObject"/> reference /// and <see cref="DomainObjectCollection"/> instances held by the object are not removed, only the data is. The object can only be unloaded if /// it is in unchanged state and no relation end-points would remain inconsistent. /// </summary> /// <param name="clientTransaction">The <see cref="ClientTransaction"/> to unload the data from. The unload operation always affects the whole transaction /// hierarchy.</param> /// <param name="objectID">The object ID.</param> /// <returns><see langword="true" /> if the unload operation succeeded (in all transactions), or <see langword="false" /> if it did not succeed /// (in one transaction).</returns> /// <remarks> /// <para> /// The method unloads the <see cref="DataContainer"/>, the collection end points the object is part of (but not /// the collection end points the object owns), the non-virtual end points owned by the object and their respective opposite virtual object /// end-points. This means that unloading an object will unload a relation if and only if the object's <see cref="DataContainer"/> is holding /// the foreign key for the relation. Use <see cref="TryUnloadVirtualEndPoint"/> or <see cref="TryUnloadVirtualEndPointAndItemData"/> to unload /// relations whose foreign keys are not held by the object. /// </para> /// <para> /// If a <see cref="DomainObject.OnUnloading"/>, <see cref="IClientTransactionExtension.ObjectsUnloading"/>, or similar handler throws an /// exception to cancel the operation, that exception is propagated to the caller (rather than returning <see langword="false" />). /// </para> /// <para> /// The unload operation is atomic over the transaction hierarchy. If the operation cannot be performed or is canceled in any of the transactions, /// it will stop before any data is unloaded. /// </para> /// </remarks> public static bool TryUnloadData(ClientTransaction clientTransaction, ObjectID objectID) { ArgumentUtility.CheckNotNull("clientTransaction", clientTransaction); ArgumentUtility.CheckNotNull("objectID", objectID); Func <ClientTransaction, IDataManagementCommand> commandFactory = tx => tx.DataManager.CreateUnloadCommand(objectID); var executor = new TransactionHierarchyCommandExecutor(commandFactory); return(executor.TryExecuteCommandForTransactionHierarchy(clientTransaction)); }
/// <summary> /// Tries to unload the virtual end point indicated by the given <see cref="RelationEndPointID"/> in the specified /// <see cref="ClientTransaction"/>, returning a value indicating whether the unload operation succeeded. If the end point has not been loaded or /// has already been unloaded, this method returns <see langword="true" /> and does nothing. /// The relation must be unchanged in order to be unloaded, and it must not belong to an object that is new or deleted, otherwise this method /// returns <see langword="false" />. /// </summary> /// <param name="clientTransaction">The <see cref="ClientTransaction"/> to unload the data from. The unload operation always affects the whole transaction /// hierarchy.</param> /// <param name="endPointID">The ID of the relation property to unload. This must denote a virtual relation end-point, ie., the relation side not /// holding the foreign key property.</param> /// <returns><see langword="true" /> if the unload operation succeeded (in all transactions), or <see langword="false" /> if it did not succeed /// (in one transaction).</returns> /// <exception cref="ArgumentNullException">One of the arguments passed to this method is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">The given <paramref name="endPointID"/> does not specify a virtual relation end point.</exception> /// <remarks> /// <para> /// If a <see cref="DomainObject.OnUnloading"/>, <see cref="IClientTransactionExtension.ObjectsUnloading"/>, or similar handler throws an /// exception to cancel the operation, that exception is propagated to the caller (rather than returning <see langword="false" />). /// </para> /// <para> /// The unload operation is atomic over the transaction hierarchy. If the operation cannot be performed or is canceled in any of the transactions, /// it will stop before any data is unloaded. /// </para> /// </remarks> public static bool TryUnloadVirtualEndPoint(ClientTransaction clientTransaction, RelationEndPointID endPointID) { ArgumentUtility.CheckNotNull("clientTransaction", clientTransaction); ArgumentUtility.CheckNotNull("endPointID", endPointID); CheckVirtualEndPointID(endPointID); Func <ClientTransaction, IDataManagementCommand> commandFactory = tx => tx.DataManager.CreateUnloadVirtualEndPointsCommand(endPointID); var executor = new TransactionHierarchyCommandExecutor(commandFactory); return(executor.TryExecuteCommandForTransactionHierarchy(clientTransaction)); }
/// <summary> /// Unloads the virtual end point indicated by the given <see cref="RelationEndPointID"/> in the specified /// <see cref="ClientTransaction"/> as well as the data of the items referenced by it. If the end point has not been loaded or has already been /// unloaded, this method does nothing. /// The relation end-point must be unchanged in order to be unloaded, and it must not belong to an object that is new or deleted. /// </summary> /// <param name="clientTransaction">The <see cref="ClientTransaction"/> to unload the data from. The unload operation always affects the whole transaction /// hierarchy.</param> /// <param name="endPointID">The end point ID. In order to retrieve this ID from a <see cref="DomainObjectCollection"/> representing a relation /// end point, specify the <see cref="DomainObjectCollection.AssociatedEndPointID"/>.</param> /// <exception cref="InvalidOperationException">The involved end points or one of the items it stores are not in unchanged state.</exception> /// <exception cref="ArgumentNullException">One of the arguments passed to this method is <see langword="null" />.</exception> /// <exception cref="ArgumentException">The given <paramref name="endPointID"/> does not specify a collection end point.</exception> /// <remarks> /// <para> /// The unload operation is atomic over the transaction hierarchy. If the operation cannot be performed or is canceled in any of the transactions, /// it will stop before any data is unloaded. /// </para> /// </remarks> public static void UnloadVirtualEndPointAndItemData(ClientTransaction clientTransaction, RelationEndPointID endPointID) { ArgumentUtility.CheckNotNull("clientTransaction", clientTransaction); ArgumentUtility.CheckNotNull("endPointID", endPointID); CheckVirtualEndPointID(endPointID); Func <ClientTransaction, IDataManagementCommand> commandFactory = tx => CreateUnloadVirtualEndPointAndItemDataCommand(tx, endPointID); var executor = new TransactionHierarchyCommandExecutor(commandFactory); executor.ExecuteCommandForTransactionHierarchy(clientTransaction); }
public override void SetUp() { base.SetUp(); _leafRootTransaction = ClientTransaction.CreateRootTransaction(); _rootTransactionWithSub = ClientTransaction.CreateRootTransaction(); _leafSubTransaction = _rootTransactionWithSub.CreateSubTransaction(); _readOnlyTransaction = new TestableClientTransaction(); ClientTransactionTestHelper.SetIsWriteable(_readOnlyTransaction, false); _mockRepository = new MockRepository(); _commandFactoryMock = _mockRepository.StrictMock <ICommandFactory>(); _commandMock1 = _mockRepository.StrictMock <IDataManagementCommand> (); _commandMock2 = _mockRepository.StrictMock <IDataManagementCommand> (); _executor = new TransactionHierarchyCommandExecutor(_commandFactoryMock.Create); }