views:

3792

answers:

4

I'm working on a personal project (C# / ASP.NET) that will use LINQ to SQL. The Solution will have (so far) a Webform project, a Namespace project (business logic), and a Tests project. I'm in the very early stages so far (clearly in Design phase).

Is there a paradigm for 3-Tier Architecture here? It seems like the DAL is entirely useless in this case; feels like I should be performing the LINQ query directly from the business logic.

It also occurs to me that if I just keep one resident DataContext and pass that around, I would only need the one open connection. This would have the added benefit of committing changes all at once instead of granularly. Any thoughts on that?

I found this thread, but it seems to paint an incomplete picture. Are there any in-depth articles on the subject?

+3  A: 

You could read up a bit on Domain Driven Design.

With the practice of Domain Driven Design (DDD), you have a rich 'domain model', in where you express the problem domain that you want to tackle. This domain model consists of classes (and structs) with which you model your business entities. The domain model also consits of repositories.
A repository is some kind of abstraction that you use in your domain model (and in your application); The repository is an abstraction of your datastore. Through the repository, you can retrieve entities, and you can use the repository to persist entities.

In your case, your Repositories could use Linq To SQL internally to talk to the database. Note however, that your repository should not be responsible to manage (open/close) the connection and the transaction (start/commit/rollback) though. Why ? -> because the Repository has no knowledge or notion of the context in which it is used. It is your application or service layer (the layer that uses your domain model and hence your repository) that should be responsible for opening a new connection and starting / committing transactions. (Or in your case, open a new DataContext). You could then pass the DataContext to the repository.

(Eric Evans has a great book regarding DDD, albeit a hard nut to crack, from time to time).

Frederik Gheysels
A: 

The LINQ to SQL library is your DAL in this case, and instead of making traditional API calls from your business layer (e.g. DAL.GetObjectById(id)) you have the flexibility of much more expressive requests into the DAL.

If you had some other needs, for example your own LINQ provider which connects to a non-MSSQL data backing, then you would implement your own DAL.

Additionally regarding the DataContext, it is not recommended to use a singleton pattern with "one resident DataContext". A DataContext object should represent a single logical transaction, whatever that means for your application. (Paraphrased from http://weblogs.asp.net/despos/archive/2008/03/19/more-on-datacontext-in-hopefully-a-realistic-world.aspx)

Rex M
+1  A: 

You should be careful with your terminology. When you say LINQ you mean Linq-to-sql and when you say 3-tier that usually means you are talking about a deployment scenario with 3 separate machines. I'm not sure if that is what you mean.

A three-layer architecture is still a good idea when using an ORM tool like linq-to-sql. The DAL becomes just a place to store your query logic. Its a good idea to take your queries out of your business layer because queries are a persistence concern, not a business logic concern.

The usual technique for managing the data context is to have a single data context per request.

In terms of other articles on the subject you can look at any architecture guidance for any ORM tool - linq-to-sql is no different. Look for articles about architecture for NHibernate.

liammclennan
hey liammclennan, is it really necessary that when you say 3-tier then it is for 3 separate machines? As far as I know 3 tier is all about code separation in 3 logical layers and I can have these 3 layers on one machine - it is the case for all 3 tier projects that I have worked till date
Manoj
There is established terminology that 3-tier means three machines. At least that is how Fowler defines it in POEAA.
liammclennan
+3  A: 

You can think of LINQ-to-SQL as your DAL, so using it "directly from the business logic" isn't necessarily a bad thing.

http://dotnetlog.com/archive/2008/03/18/best-practice-and-effective-way-of-using-datacontext-in-linq.aspx has some popular L2S approaches listed.

On our project, we did not want to pass around the data context so we used a pattern similar to #3 from the above link (Ambient DataContext, see below). It had some issues, but it worked reasonably well; at least for our web project.

Ambient DataContext (Currently using this)

The idea behind ambient datacontext is that context is created for a particular thread or a httpcontext(in asp.net) as soon as there is a first call for the DataContext. Then the same context is used for that thread or request unless it is disposed manually. This is done by storing the context in the request/thread data store. The approach to this pattern is similar to static DataContext, however, separation is provided for each thread and requests. This works really well in Asp.Net, however, is again plagued by some of the problems of static context.

Problems with this pattern:

* The context is available for manipulation at any level. And quickly becomes very hard to maintain unit of work
* Portability across thread is very hard
* Unit of work pattern is not transparent enough
Giovanni Galbo
link does not work
jlp