Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ to SQL and the repository pattern

I feel like I'm running around in circles. I can't seem to make up my mind as to what the right repository pattern is using LINQ to SQL. If you're familiar with Rob Conery's MVC Storefront you will see that his implementation wraps the LINQ-generated models with another class and treats the LINQ-generated one simply as a data transfer object (DTO). It looks something like this:

//Custom wrapper class. namespace Data {     public class Customer     {          public int Id {get;set;}          public string Name {get;set;}          public IList<Address> Addresses {get;set;}     } }  //Linq-Generated Class - severly abbreviated namespace SqlRepository {     public class Customer     {          public int Id {get;set;}          public string Name {get;set;}          public EntitySet<Address> {get;set;}     } }  //Customer Repository namespace SqlRepository {     public class UserRepository : IUserRepository     {         private _db = new DB(); //This is the Linq-To-Sql datacontext          public IQueryable GetCusomters()         {             return                 from c in _db.Customers                 select new Customer // This is the wrapper class not the gen'd one                 {                    Id = c.Id,                    Name = c.Name,                    Addresses = new LazyList(c.Addresses)                 };         } 

What is the advantage of doing it this way (using a wrapper class), as opposed to the way Mike Hadlow suggests in Using the IRepository pattern with LINQ to SQL in his version of IRepository<T> where he just returns the DTO objects from the repository?

Where should the business logic be enforced and checked? Is this in a seperate layer all together called by the repository on save/update, or is it built-in to the wrapper class?

like image 799
Micah Avatar asked Jan 20 '09 11:01

Micah


People also ask

How does a LINQ query transform to a SQL query?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

Is LINQ to SQL an ORM?

LINQ to SQL is an object-relational mapping (ORM) implementation that allows the direct 1-1 mapping of a Microsoft SQL Server database to . NET classes, and query of the resulting objects using LINQ.

Is LINQ to SQL still used?

LINQ to SQL was the first object-relational mapping technology released by Microsoft. It works well in basic scenarios and continues to be supported in Visual Studio, but it's no longer under active development.


1 Answers

The thing is this, LINQ to SQL is not a true Object Relation Mapper (ORM), it is a data access layer generator. You can make it be an ORM by going deep by hand editing XML files and playing with SqlMetal and whatnot, but where it shines is as a DAL.

The idea behind an ORM is this. You have your SQL database, and your domain objects. To design a database properly, you are going to do things (like normalization) that logically don't translate into a properly designed object model, and vice-versa. This is called "Impedance Mismatch", the role of an ORM is to deal with that mismatch in a clean, effective, and efficient way. The less painful database interaction is almost a secondary thing.

The idea behind a repository is that it encapsulates all persistence logic and dependencies on infrastructure from the rest of your application. When your application needs a Customer object, it shouldn't have to know whether it is coming from SQL Server, MySQL, an XML file, or ASP.NET Membership. Once you have that de-coupling, any changes you make to your persistence story have no effect on the rest of your application.

With that in mind, it gets more clear why he did what he did. LINQ to SQL is used to generate the DAL, but the only thing that should be known about the DAL is the repository, so a translation is made to his domain objects. That way he can refactor his domain model without worrying about his persistence story, and he can refactor his database without worrying about rippling effects through his application. He could also start coding on business logic before deciding on questions like what ORM to use, or even where to store his data.

If he were to use a real ORM (like NHibernate), that mapping code gets handled elsewhere (either in XML or bootstrapping classes). I think LINQ to SQL (and Robs open source DAL, SubSonic) are great projects, but more designed for smaller, two-tier applications where something like the repository pattern is overkill. The storefront is also a good illustration of why the additional complexity of NHibernate can be important. He could have saved himself a lot of code by going with something built to handle that sort of scenario, rather than doing it all manually.

like image 117
Matt Briggs Avatar answered Sep 27 '22 22:09

Matt Briggs