views:

273

answers:

7

I'm looking at using LINQ to SQL for a new project I'm working on, but I do not want to expose the LINQ classes to my applications. For example, do an select in link returns a System.Linq.IQueryable<> collection. As well, all the classes generated to represent the database use Table, Column, EntityRef classes and attributes. It's fine if my data access layer has LINQ dependancies, but I don't want my application to.

So my thoughts are that I will have to use the LINQ to SQL generated classes as intermediate classes that are not exposed outside of my data access layer, and create my own classes which the application can use. What is the easiest/effecient way to get the data from the LINQ to SQL classes into my own classes?

+1  A: 

Rob Conery published a webcast series entitled the MVC-Storefront where he introduces a variation of the repository pattern that accomplishes what you want.

I've used ideas from the screencast on a reasonably large project and was quite pleased with the results.

There are, however, issues with the pattern, particularly around concurrency and detached scenarios that you will want to think about up front before fully committing to it.

I detailed some of my pain with concurrency in this pattern here.

David Hall
A: 

To go from the Linq to SQL classes to your classes is a matter of some fairly straightfoward Linq to Objects (or just initialisation for single objects).

More fun is going back from your model to the Linq to SQL objects but this is fairly standard stuff (although something I'm still working out or I'd find you some specific references)

Murph
A: 

I'll be interested in the responses you get because I'm considering the exact same thing. I want to use the L2S entities classes on our backend but use much lighter-weight entities for application consumption.

Randy

Randy Minder
A: 

This is my current incarnation of how I am going about doing this:

I have a DataContext class that I created by adding a LINQ to SQL class, and droping tables onto the designer. I called the class MyDataContext and put it in a namespace called Linq. My database has a table called Tag, which generated a class, also in the Linq namespace. I changed all the accessors to internal, so they would not be visible outside of the data access layer.

namespace Linq
{
    [System.Data.Linq.Mapping.DatabaseAttribute(Name="MyDb")]
    internal partial class MyDataContext : System.Data.Linq.DataContext
    {
        ...
    }

    [Table(Name="dbo.vTag")]
    internal partial class Tag
    {
        ....
    }
}

I then created a class called DataAccess which is what will be exposed to any application that references the assembly. I also created my own Tag class. The DataAccess class and my new Tag class are in a different namespace called Data to avoid collisions with the generated classes which are in the Linq namespace. I use Linq to Sql to query for an IList of Linq.Tag objects, then I use Linq to generate me a list of Data.Tag objects from the Linq.Tag objects.

I'd like to hear comments on this to see if there's a more performant way to do this, or one that requires less code. I also wasn't too happy with my use of duplicate class names (Tag) so I'm interested to hear any ideas on naming suggestions too.

namespace Data
{
    public class DataAaccess
    {
        public IList<Tag> List_Tags()
        {
            using (Linq.MyDataContext dal = new Linq.MyDataContext ())
            {                
                IList<Linq.Tag> lstTags =  (from c in dal.Tags select c).ToList();

                return (from tag in lstTags
                        select new Data.Tag()
                            {
                                ID = tag.ID,
                                Name = tag.Name,
                                Parent_ID = tag.Parent_ID
                            }).ToList();
            }
        }
    }
}
Jeremy
A: 

I would advise against using LINQ to SQL on a new project, since Microsoft will no longer be developing this project, except for maybe fine-tuning some issues. LINQ to SQL is perfectly usable and is acceptable, but I would not advise new projects to use it. If you like LINQ to SQL, you should definately look into using Entity Framework instead of LINQ to SQL.

CodeMonkey
I did not know this, and did some googling to find sources that backed up your comment. There were many the seemed to confirm your comment, but I did find this one that offered a little more insight. It appears that LINQ to SQL will not die outright, but will merge with the entity framework and continue evolving:http://www.infoq.com/news/2008/11/DLINQ-Future
Jeremy
A: 

What you are proposing is having two seperate models. That means boilerplate code, which I've found is not necessary. I have more or less the same idea as you, but realized that this would be useless. I've suggested Entity Framework in another answer in this thread, and I want to make that point again here.

What you end up with is a Model-soup, where you have to maintain two models instead of just the one. And that is definately NOT desirable.

CodeMonkey
I tend to agree, it is somewhat of a two model hybrid, but how else do you suggest removing the underlying dependancies (linq to sql, or entity framework) from being passed up to the application?
Jeremy
You can always use tools like AutoMapper (from Codeplex) to do this for you painlessly...... http://www.codeplex.com/AutoMapper
marc_s
+1  A: 

I totally agree with your thinking - I would try to avoid exposing LINQ-to-SQL entities directly to the world.

I would definitely recommend using a "domain model" of your own, either a 1:1 mirror of the underlying LINQ-to-SQL entities, or a different one.

As long as you have a domain model that is quite similar to the underlying Linq-to-SQL entities, you can use tools like AutoMapper to easily shuffle data between your Linq-to-SQL entities and your domain model classes. Should be pretty easy and flexible to do it that way!

Marc

marc_s