Skip to content

How Dapper.SimpleSave works

Bart Read edited this page Oct 30, 2015 · 5 revisions

For pattern junkies, Dapper.SimpleSave encapsulates an implementation of a well known enterprise architeture pattern known as Unit of Work. It also assumes that the objects it saves are a bit like Row Data Gateways (though if you're just working with DTOs, they're not really).

The process by which Dapper.SimpleSave saves data to the database is as follows:

  1. Perform a deep comparison between the current object and the previous version of that object, and build a list of differences.

  2. Use the list of differences to build a list of operations that describe the changes that need to be made to the corresponding database rows to make them match the new version of the object.

  3. Use the list of operations to build a list of commands that will provide the template for the SQL that will be generated - in particular coalesce updates into a single command for each row.

  4. Use the list of commands to build the minimum number of parameterised SQL batches that will update the database with the required changes.

  5. Execute the SQL batches sequentially as a single database transaction to update the database, resolving any previously unknown primary key values before each batch is executed.

Since SQL Server does not support deferred referential integrity checks, implicit in the above is that operations are performed in the correct order to ensure that referential integrity is maintained throughout the duration of the transaction. We do not yet have an explicit topological sort step, but rather imply this with the order in which the list of operations is built. Therefore, there are possibly situations where script execution will fail that we haven't yet encountered.

Should such a situation arise there are a number of options:

  1. Raise a bug against Dapper.SimpleSave. We'll evaluate it as a community and decide on the best course of action (we might choose to fix, or not fix because we choose not to support certain scenarios - for example if such a scenario is very rare, yet disproportionately complex to support).

  2. You can fork Dapper.SimpleSave, fix the bug, and submit a PR (we'd like this a lot).

  3. You could tactically remove or alter foreign key relationships in the underlying database - in particular we recommend you avoid circular relationships (these are explicitly NOT supported already).

  4. Make isolated use of a more full-featured ORM, such as EF.

  5. Write Raw Dapper or ADO.NET custom code to update the database.

  6. For particularly complex bounded contexts, a CQRS approach may be justified but this really should be an option of last resort.

For more details on (1) and (2), please see contributing.md.

Clone this wiki locally