SubmitChanges events

All changes to SQLDataContext are submitted back to database with SubmitChanges method. SubmitChanges has multiple steps that you can use to customize data validation and data content. SubmitChanges will execute following steps:
  1. Call ValidateRow on all objects implementing ITableRowValidate interface
  2. Create transaction
  3. Call BeforeDatabaseChanges on all objects implementing ITableRowCommit
  4. Fill compare and/or update parameters with GetParameters from ITableRow and execute insert/update/delete with given parameters
  5. After insert call SetIdentity on object implementing IEntityCreated. Steps 4 and 5 will repeat one row at a time.
  6. Call AfterDatabaseChanges on all objects implementing ITableRowCommit
  7. Commit transaction
In every step objects are handled in same order than they were inserted, modified or deleted.
You can abort the transaction at any phase by throwing an exception.

Next examples will use the AddressEntity defined earlier.

ValidateRow (step 1)

This step should be used to validate any data. This step can also be used to calculate values for some properties.
#region ITableRowValidate Members
public void ValidateRow(RowStates state,
    ITableRow originalValues, ICommitContext context) {
    if (CheckCountry(Country))
        throw new ApplicationException("Invalid country " + Country);
}

BeginTransaction (Step 2)

The physical database transaction is begun.

BeforeChanges (Step 3)

This step can be used to perform additional steps before the changes are committed. You can perform operations based on the set of records that will be deleted or updated before changes are actually done. See the example at the AfterChanges step description.

Fill data (step 4)

This step is normally handled with generated code. You can implement a more advanced logic to select what values are included in insert or update and what condition to apply for update or delete.

For example, you can skip some columns in update or insert based on other criteria.
protected override bool IncludeValue(ParameterSets set, string propertyName) {
    if (propertyName == "Region" && !HasRegion(Country))
        return false; // Skip the region if not applicable for the country
    return base.IncludeValue(set, propertyName);
}

SetIdentity (Step 5)

This step can be used to distribute newly assigned ID to related objects. This handler is needed if you have database constraints and identity columns in use. For example, you must implement this interface and the event handler to assign the parent ID to the child objects before the child objects are inserted into the database.
#region IEntityCreated Members
public event Action<int> HasID;
public void SetIdentity(long newIdentity) {
    if (HasID != null)
        HasID((int)newIdentity);
}

AfterChanges(Step 6)

This step is like BeforeChanges but it will be called after the changes have been performed. You can perform calculations etc in this step.
public void AfterDatabaseChanges(RowStates state, 
    ITableRow originalValues, ICommitContext context) {
    // Add custom login here
    ParameterList pl = new ParameterList();
    pl.Create("Address").ToSql(Address);
    pl.Create("Country").ToSql(Country);
    if (state != RowStates.Deleted)
        context.ExecuteProcedure("AddressInUse", pl);
}

ICommitContext can be used to execute stored procedures. ICommitContext has an optional used defined state parameter that can be set in SubmitChanges class. This parameter can be used to access application specific context.

CommitChanges (Step 7)

Back to index

Last edited Oct 26, 2010 at 10:05 AM by nolics, version 4

Comments

No comments yet.