I’m going to coin the phrase ‘Functional Transparency’ because it fits the definition. I’ve been working with functional transparency in LINQ to SQL for a few weeks now, and it seems to be working well enough to write about.
The objective is to implement additional (background) functionality which is not seen by calling/consuming code – hence, transparent. In fact, it’s even possible to enforce execution of certain functionality no matter how a DataContext is manipulated – neat, huh?
In other words, we implement additional functionality between the DataContext, its entities and the Database itself. Our objective may be to modify the data returned from a query (or data saved to a database), might be to audit operations or even check access permissions – but all done so without the knowledge of the calling code.
A perfect scenario would be for encryption/decryption of column (property) values (i.e. values are stored encrypted but read/written in clear text)… Another great use would be for item tracking or auditing.
For example, we might want to be sure that when an entity is saved or deleted, that a record is made of the change. We could do that without requiring an explicit call to a logging or auditing routine.
The LINQ to SQL object model allows us to work behind the scenes to facilitate this kind of functionality. To work our magic we need to extend the working Data Context – mostly due to the nature of LINQ to SQL. So by simply using partial classes we can easily extend the entity classes and the Data Context class and implement as necessary.
There are a couple of other issues which may crop up when working a little more closely with the Data Context and Entity definitions – beware the DBML!
LINQ uses it’s own style of optimistic concurrency by updating and then retrieving a row back by executing a select command with the updated parameters in a where clause. This is problematic if values are not likely to be the same between database reads. To get around this some columns (timestamps, for example) require the UpdateCheck=Never attribute to be added to the DBML.
In the next article in this series, I’ll go into more detail, and also start providing examples of how we can implement some seriously wicked transparent functionality. Hopefully the power of this flexible approach will become apparent.