TechTalk Genome v4.2

Context.AfterUpdateObject Event

Raised for all persistent object that have been saved in the DataDomain in this Context as a last step the of the update roundtrip.

public event UpdateEventHandler AfterUpdateObject;

Implements

IContext.AfterUpdateObject

Remarks

Genome synchronizes unsynchronized persistent objects with their DataDomains in bursts of updates as directed by the transaction strategy of the given Context. Depending on the transaction strategy several update batches can execute before the changes done in the Context finally get committed or aborted. The same persistent object might be synchronized in multiple update batches within the same logical transaction depending on usage scenarios and the transaction strategy.

The AfterUpdateObject event is raised for every persistent object involved in an update batch. The order in which the AfterUpdateObject events are raised for the individual persistent objects is indeterministic however the subscriber can assure that any involved persistent objects get notified only after the last update operation have been performed against all databases. If the update batch is initiated by a call to Commit all AfterUpdateObject events are dispatched before the first AfterCommitObject event would be raised.

The subscriber of this event may not modify persistent objects, execute implicit or explicit queries within the given Context. It is however possible to execute T-SQL statements in the context of the physical transaction using the Transaction and Connection parameters. Since the event execution order is indeterministic however the executed T-SQL statemets must not depend on a certain execution order.

This event is raised for any persistent object that is being synchronized in the current update batch. The concrete operation (INSERT, UPDATE, DELETE) being performed on sender is indicated by the value of the UpdateEvent parameter. When signaled for deleted persistent object the object proxy specified in sender is only partially valid and only fields participating in object identity are accessible.

Events raised by the Context can be captured from different areas of interest. The developer may choose to capture a certain event originating from a certain Context by subscribing to one of the Context events using the standard .NET event mechanism. This allows for multiple queued event processors and dynamic strategies in handling events. The order in which subscribers are notified is nondeterministic and hence no subscriber should perform operations with side-effects that would affect the execution of other subscribers or that assumes a certain execution order. This way of processing Context events is similar to handling events raised by ADO.NET DataTable.

The developer might optionally choose to process Context events on persistent objects directly. In this case the class implementing persistency should be inherited from the corresponding callback interface. Each callback interface defines one method to implement with a similar signature as the corresponding event delegate. When the Context raises an event for a persistent object it executes the callback method whenever the object implements the appropriate callback interface. This practically ensures that the object is always subscribed to all events of any Context that it is interested in regardless of how the Context itself is configured by the caller.

The Context that raises the event will automatically become the active Context in the calling thread for the duration of the call. This ensures that any unbound proxies used in the event handlers are resolved from the relevant Context. When the events have been successfully processed, the context stack of the calling thread is restored to its previous state.

Example

class Forum : Persistent
{
    public abstract Guid Id {get; set;}
    public abstract int MessageCount {get; set;}
}

class Message : Persistent, IAfterUpdateCallback
{
    public abstract Forum Container {get; set;}
    
    void IAfterUpdateCallback.OnBeforeUpdate(UpdateEventArgs args)
    {
        if( agrs.UpdateEvent == UpdateEvents.Delete )
            return;
    
        // updating the message count of the forum containing this message
        IDbCommand cmd = args.Connection.CreateCommand();
        cmd.Transaction = args.Transaction;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "UPDATE [Forum] SET " +
            "MessageCount = (SELECT COUNT(*) FROM Message WHERE ContainerId = @ContainerId) " +
            "WHERE Id = @ContainerId";
        
        IDataParameter forumId = cmd.CreateParameter();
        forumId.DbType = DbType.Guid;
        forumId.Direction = ParameterDirection.Input;
        forumId.ParameterName = "@ContainerId";
        forumId.Value = Container.Id;
        cmd.Parameters.Add(forumId);

        cmd.ExecuteNonQuery();
    }
}
                    

Requirements

Namespace: TechTalk.Genome

Assembly: TechTalk.Genome (in TechTalk.Genome.dll)

Version: 4.2.11.59

Editions: Professional, Evaluation, Express

See Also

Context Class | TechTalk.Genome Namespace | IAfterUpdateCallback | BeforeUpdateObject