James Hollingworth’s Adventures in Code

Problems with the Linq2Sql

with 5 comments

I have just been reading Scott Guthrie’s post on the new ASP.Net MVC framework. Firstly, for the most part I am really amazed with what Microsoft have come up with and I am really looking forward to having a play with it. I am worried though about the methods Scott uses for creating models for data access. In the examples he creates a Linq2Sql model for data access and then use the the database context class to encapsulate all the business logic. Anyone see any problems with this? Say you have a User table in the database, Linq2Sql will create a user object which you can perform all the basic CRUD operations. Say you want to add a method to check if a given user has valid username & password (basic business logic), which of these would you think is logical?

DataBaseContext db = new DataBaseContext();
db.IsUserValid(username, password);

or

User.IsValid(username, password);

IMHO the second is far better since firstly when writing code you don’t need to be aware of other objects (i.e. database context) to be access the business logic of that object. Also having all the business logic encapsulated in the actual object enforces code separation so it is easier to maintain since there will only ever be one file which contains all the code relating to the object. Also

So what should you do instead of encapsulating the business logic in the context? Well there are 2 methods which would allow you to encapsulate all your business logic, the first being using partial classes. Using the User example again, say Linq2Sql has created a User object, you would add another file in the Model directory and create a partial class which you can then include all business logic, as shown below:


partial class User
{

public static bool IsValidLogin(string userName, string password)
{

//Some business logic
return true;

}

}

This method will allow separation of code and you don’t need any knowledge of extra classes to use it. Unfortunately this method is soooo .Net 2.0, so for everyone who is needing an excuse to use the new extension methods, here it is:


public static class UserBusinessLogic
{

public static bool IsValidLogin(this User user, string userName, string password)
{

//Some business logic

return true;

}

}

Both methods work fine and will enforce code separation. Its a shame that decided on having a single .dbml file for the models and Context file for the business logic. I would have thought having an individual class for each table in the db (with a partial class containing all auto generated code) would be more logical and scalable.

There are fundamental flaws with this like how do you apply rules to properties (e.g. ensuring that a password is > 7 characters)? Currently this sort of business logic is enforced at the database end which is a bit crap since I thought the whole point of Linq2Sql or any ORM was so the developer doesn’t have to deal with the database!

While I am critical of Linq2Sql, it is still early days and I’m sure as time passes they will rectify the problems highlighted here. Until then, I hope the methods shown here will help you write maintainable code!

kick it on DotNetKicks.com

Written by jhollingworth

November 13, 2007 at 3:23 pm

Posted in .net, c#, linq

Tagged with

5 Responses to 'Problems with the Linq2Sql'

Subscribe to comments with RSS or TrackBack to 'Problems with the Linq2Sql'.

  1. i think, putting custom business logic code to seperate partial classes is more acceptable.

    Dbml file is auto-generated by visual studio fetching all database objects and key constraints. So when you make a change in your database design, you will require to update dbml file by re-dropping tables to designer and if you put your custom logic into the datacontext class your custom changes will be lost i guess.

    You bet you could synchron database changes manually in the auto-generated code but it’s not the easy and robust way i think.

    Kadir Pekel

    13 Nov 07 at 4:09 pm

  2. [quote]
    Its a shame that decided on having a single .dbml file for the models and Context file for the business logic
    [/quote]

    I always thought of the dbml as being the datalayer.
    Have i misinterpreted the quoted text and what you meant is ‘for consumption by the business logic layer’?

    Your business object “User” would have an “IsValidLogin” function that uses the DataContext to do what it needs to do. Of course it is debatable whether your BL should be DataContext aware or DataContext agnostic by accessing the DL through some wrapper of the DataContext class rather than directly.

    I think having a DataContext aware BL keeps things simpler rather than adding another abstraction layer in between

    Anastasiosyal

    13 Nov 07 at 10:25 pm

  3. @Anastasiosyal
    You are correct in saying the dbml file represents the datalayer, i.e. the models for an MVC web app, but the point I am trying to make is that there is currently no method (apart from ones highlighted) for adding the business logic in a way which is maintainable.

    Where you are wrong is that saying that I am adding a layer of complexity, the DataContext is in fact the one adding complexity. Having a single object to handle the business logic for all other objects is going to lead to one massive un-maintainable mess where there is no clear separation of code.

    It also means the developer has to be aware of the DataContext class instead of just the object you are working with. This is important since I feel you should always leave your project in a state which anyone, with a general understanding of the domain, can pick up and start developing.

    My method isn’t adding an extra layer, it is merely adding functionality to the data access layer in a maintainable manner.

    jhollingworth

    13 Nov 07 at 10:57 pm

  4. Maybe the point of the debate is confused by the fact that your IsValidLogin() method’s true implementation is not shown. Would you write your own direct DB (stored proc or otherwise) code to validate the username/password, would you add a stpred proc to the .dbml model, etc.?

    Troy DeMonbreun

    14 Nov 07 at 11:24 pm

  5. I have personally always seen ORM’s like Linq2Sql as a reason to keep all the code in the application, rather than splitting the it bits of code in the database. It makes for much easier development since it is far easier to debug c# rather than a tsql, although vs professional has made debugging sp’s just as easy. Using ORM’s over SP’s has other benifits like developers only needing a basic understanding of SQL, it also makes source control far easier. While SP’s have their negative points, currently they are the most mature way of enforcing business logic in .net applications. Hopefully as Linq2Sql improves, we can move more away from using SP’s and putting the code in the application where I feel it belongs.

    jhollingworth

    15 Nov 07 at 12:08 am

Leave a Reply