Thursday, December 13, 2007

Linq

I have been playing with Linq (Linq to Sql) for a couple of weeks, when I get a chance. I do like Linq. The most powerful (and obvious) feature is automating the plumbing of creating a data-access layer. Design the database, drop the tables with links on the designer and bam, you're done.

While this is a really good thing, I think there are two potential issues:

1) Linq can promote tighter coupling of UI to DataLayer (DataContext in this case)
Maybe this isn't as big an issue as it used to be in the bad old days, but I can see lazy coders talking directly to the dataContext/Layer from the UI. For example

myDataGrid.DataSource = MyDataContext.Customers;

it probably isn't a sin but it's a small step from there to embedding business logic in the UI layer because it is so easy to do something like

string id = txtId.Text;
var cust = from customer in MyDataContext.Customers
      where customer.id == id
      select customer;

someControl.DataSource = cust;

in a search button on click event. This sort of thing was/is common in Delphi. Delphi has a concept of a Datamodule, which isn't a million miles away from a DataContext. Well I guess it is, but for arguments sake, if you think of a DataContext as a central data repository then a Delphi data module is getting closer. It makes ugly, hard to maintain code. So please don't ever do this. Use Linq to Sql by all means, but there is no reason not to still have a business layer in between.



2) Linq to Sql will generally create a 1:1 mapping of data objects to business objects
A lot of people don't care about this, but business objects shouldn't necessarily be a 1-1 mapping of your tables. Take an order for example, it will contain data from a number of different tables, customer, order master, order detail, product, possibly tax. Anyway you get my point. From a business object point of view, this is one object.

Without discipline, good design, and buy in, linq makes it very easy to cobble bits of data together to do what you need quickly and easily, in the short term, but can cause a mountain of headaches in the maintenance phase. I have seen it all to often in Delphi code.

I guess in a nutshell, the point of this post boils down to this statement:

Linq offers great power, but with great power comes great responsibility. Please, please, please remember this when you are dipping your toes into the Linq pool for the first time.

1 comment:

Anonymous said...

On your point 2) I see what you're saying and agree that there's always a bit of a disconnect between the community examples of data implementations and the real life practical situations that need to be realised.

It's probably fairer to say that in a lot of cases, where a project is large, and has DBAs who jealously guard their databases, schemas etc, that LINQ DataContext classes are more likely to be bound to views and stored procedures rather than to individual tables.

The "more complex entities" problem was there with ADO.NET and earlier and I'm not sure the default LINQ-to-SQL even tries to do anything about that. It's still going to be down to the DAL/BAL to aggregate and mangle what it gets back from the DB into your "complex entity" for sending to the presentation layer.