Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Personally I hate the design pattern whereby one adds a "IsDeleted" column to a table. The reasons are numerous.</p> <ol> <li>The pattern produces an inner platform, you have a database inside a database.</li> <li>Custom API required to access the inner database (<code>select * from table where IsDeleted = 0</code>) and (<code>delete from table becomes update table set IsDeleted = 1</code> )</li> <li>Extra data in table reduces performance</li> <li>Extra data is not useful for audit purposes, if you want auditing, do it properly.</li> </ol> <p>The pain-point you have met is 2. Custom API. Entity Framework was created to work against SQL databases, not some weird data-store that exists inside the SQL database.</p> <p>The solution I have discovered to this problem is to employ SQL Server Views. MS SQL Server supports Views, which you can filter on rows with your soft delete on. I would then add a <code>TRIGGER INSTEAD OF INSERT,UPDATE, DELETE</code> on the view to map your inserts/update/deletes to the correct actions on your database.</p> <p>However when using any form of abstraction you will find performance to decrease. In this case the major trade off is <code>SELECT</code>. With SQL Server Enterprise Edition it is feasible to add an index on your view (and have SQL Server automagically use the index) to speed up all your selects, at the expense of write access. That takes care of point 3.</p> <p>As for point 4. I prefer instead of a <code>IsDeleted</code> column to use the following schema...</p> <ul> <li><code>ValidFrom DateTime NOT NULL</code></li> <li><code>ValidTo DateTime NULL</code></li> <li><code>EditedBy VARCHAR NOT NULL</code></li> </ul> <p>When you create a new row, you set ValidFrom to <code>UTCNOW()</code> and EditedBy to <code>CURRENTUSER()</code>. When you update a row you set the old row's ValidTo to <code>UTCNOW()</code> and create a new row with the correct values. When you delete you set the old row's ValidTo to <code>UTCNOW()</code>.</p> <p>This schema allows you to have a full historic view of your table at ANY POINT IN TIME. Full Auditing. :)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload