views:

169

answers:

2

I'm trying to get at the best way to seperate the concerns of my domain logic and my persistence logic. I'm using Linq-2-Sql for the data access and I've been following the NerdDinner tutorial. If you look at page 40, you can see they are using partial classes to business rules to their Linq generated classes. To me, that feels wrong (is it?) and I'd like to have my own POCOs that are exposed to the presentation tier of my application. It looks like one option here, is to use a seperate DTO class. That feels better to me but it adds a lot more code to test and maintain.

I like the simplicity of simply adding partial classes to enforce business rules on the Linq classes, but I don't like exposing the Linq classes to my presentation tier, since if the database changes I'll need to update the presentation tier as well.

The DTO approach feels cleaner, since I'd never need to update the presentation tier if the database changes, but it is a lot more code to deal with.

My current approach is thus, two Class Libraries one with Linq-2-Sql DBML + Partial Classes, and the second with a set of classes that have nothing but auto-generated properties and then a "repo" class that manages getting data from the Linq assembly and converting it to IQueryable<T>.

Is there a better way? Is there a better middle ground? Can I take the best of both worlds? If so, how would you seperate them into different assemblies?

update

Maybe, what I really need to do is consolidate all of the Persitence/Domain logic into a single assembly (the same approach used in the NerdDinner sample), and then create different "View Objects" in my presentation tier, that are denormalized versions of my Linq-2-Sql Entities?

+3  A: 

I try to keep my domain objects as persistence ignorant as the technology that I'm using will allow. For LINQ to SQL, I followed the approach set out by Ian Cooper (see Being Ignorant with LINQ to SQL, Architecting LINQ to SQL Applications, Part 5 and Architecting LINQ to SQL Applications, Part 6). Basically, you can manually code up your domain objects and wire them up to LINQ to SQL using sqlmetal to generate the mapping to the database which you can then hand edit to suit your needs. It's worked quite well for me.

Jeremy Miller has a good article on the topic of persistence ignorance in MSDN magazine. See The Unit Of Work Pattern and Persistence Ignorance.

My current approach is thus, two Class Libraries one with Linq-2-Sql DBML + Partial Classes, and the second with a set of classes that have nothing but auto-generated properties and then a "repo" class that manages getting data from the Linq assembly and converting it to IQueryable<T>.

I don't like this approach. It violates DRY so violently.

Jason
I agree it goes against DRY, that's why I posted here, because it feels wrong. Should I simply ditch the middle tier and access the persistence tier directly from my presentation code? The XML Mapping files, don't really provide any extra ignorance. I still have a single class that represents my DB and Presentation...
Nate Bross
The XML mapping files do help with ignorance; they keep you from having to decorate your domain classes with technology-specific persistent-aware attributes etc. I share my domain classes between my layers (including the persistence layer and the presentation layer). I have a logic layer between the persistence layer and the presentation layer.
Jason
I guess I wasn't worried about the attributes that the Designer adds on the generated classes, I am mostly concerned with the underlying schema.
Nate Bross
@Nate Bross: You said "I don't like exposing the Linq classes to my presentation tier, since if the database changes I'll need to update the presentation tier as well." This means that you basically have two options. The first is two set up up a mapping from your LINQ to SQL classes to domain classes. The second is to make your domain classes persistence ignorant. The first requires you to maintain two classes (LINQ to SQL, domain). The second does not require this. This is why I favor the second.
Jason
OK, I see what you're saying. Thanks for the response!
Nate Bross
A: 

Have you seen AutoMapper? If you look at the blog you will see the situation you describe.

RichardOD