"Working on the complexity that is always indirectly implied by simpilicity."

Thoughts on Developing a Linq To SQL Layer

Amplify is going to have a Data Namespace that will serve as a basis for dealing with data including, validation, database migrations & fixtures similar to rails and even give some basic patterns to use.  One of these patterns will be an Active Record pattern and another will be a Repository pattern, since the repository tends to favor Linq to Sql.

One of the biggest debates on is whether or not it supports the scenario. Of course many people are still confusing the difference between physical Tiers and virtual layers in code (DAL is a data access layer, not a tier). Linq to Sql can support layers out of the box, depending on how the developer uses the generated objects.   Linq to Sql does not support WCF out of the box and you pretty much have to really massage Linq to Sql in order work disconnected, even within a Web Environment the default tight relationship between an object and the DataContext can be a bit of a pain. Linq to Sql does follow Domain Driven Design heavily.

With Asp.Net Mvc on the horizon, I think it would be proper for a Linq to Sql to have some form of an harness that provides much of the same functionality as possible as the Rail's Active Record does. Obviously c# is not ruby and a developer can not do everything the same way in c# that you can in ruby.  A good reason to get as close as possible to rails api for active record is to simply help developers who know specific concept like rails active record to hit the ground running with Amplify. 

The reason I see for doing creating an Active Record for Linq to SQL is so that you can wrap validation, business/domain logic and encapsulate it into one object, versus having to know where the separate rules are kept for data, which can create a simpler api for the developer and clue a person to in to what the domain entity is capable of and should be able to do.  This would hopefully shield the developer from being tempted to do the following with Linq to Sql, which could lead to invalid data or even worse. 

	private void Bind() { // bad practice
		using(DataContext db = CreateContext()) {
 			this.datagrid.DataSource = (from o in db.Clients select o);
			this.datagrid.DataBind();
		} 
	}

Which is a good reason for Amplify to help provide some basic interfaces and even base classes / wrappers for Linq. Now the question is, what do you support? Do support the linq objects that sqlmetal generates, provide your own CodeGen tool for Visual Studio?  Since generates the partial onPropertyNameChange methods which are crude and does not help to reduce code or really support code reuse. If you support classes that SqlMetal generates, you need to use some form of Reflection or a Linq Expression to do any kind of business rules evaluation of the incoming values.  Do you create your own kind of UnitOfWork pattern and force Linq To Sql to work disconnected and keep track of your own changes, if not what is the best way of keeping track of the DataContext that your object is now tied to? 

And if you do your own UnitOfWork pattern, you have to either add a binary timestamp or int version to the table or you have to keep the intial values of the object stashed or you have to fetch the current object in the database in order to use DataContext.GetTable<T>().Attach(entity, oldEntity); Not exactly what I would call very performant (yes I know, its not in the dictionary, but I like the word performant).

If you have any comments, suggestions, questions, feel free to drop me a line.

Labels: , , ,