|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here.|
Responsibilities of the Developer In Overriding Default Behavior (LINQ to SQL)
LINQ to SQL does not enforce the following requirements, but behavior is undefined if these requirements are not satisfied.
Override methods cannot be used to start, commit, or stop a transaction. The SubmitChanges operation is performed under a transaction. An inner nested transaction can interfere with the outer transaction. Load override methods can start a transaction only after they determine that the operation is not being performed in a Transaction.
Override methods are expected to follow the applicable optimistic concurrency mapping. The override method is expected to throw a ChangeConflictException when an optimistic concurrency conflict occurs. LINQ to SQL catches this exception so that you can correctly process the SubmitChanges option provided on SubmitChanges.
Create (Insert) and Update override methods are expected to flow back the values for database-generated columns to corresponding object members when the operation is successfully completed.
For example, if Order.OrderID is mapped to an identity column (autoincrement primary key), then the InsertOrder() override method must retrieve the database-generated ID and set the Order.OrderID member to that ID. Likewise, timestamp members must be updated to the database-generated timestamp values to make sure that the updated objects are consistent. Failure to propagate the database-generated values can cause an inconsistency between the database and the objects tracked by the DataContext.
It is the user's responsibility to invoke the correct dynamic API. For example, in the update override method, only the ExecuteDynamicUpdate can be called. LINQ to SQL does not detect or verify whether the invoked dynamic method matches the applicable operation. If an inapplicable method is called (for example, ExecuteDynamicDelete for an object to be updated), the results are undefined.
Finally, the overriding method is expected to perform the stated operation. The semantics of LINQ to SQL operations such as eager loading, deferred loading, and SubmitChanges) require the overrides to provide the stated service. For example, a load override that just returns an empty collection without checking the contents in the database will likely lead to inconsistent data.