views:

248

answers:

5

I had a client ask for advice building a simple WPF LOB application the other day. They basically want a CRUD application for a database, with main purpose being as a WPF training project.

I also showed them Linq To SQL and they were impressed.

I then explained its probably not a good idea to use that L2S entities directly from their BLL or UI code. They should consider something like a Repository pattern instead.

At which point I could already feel the over-engineering alarm bells going off in their heads (and also in mine to some extent). Do they really need all that complexity for a simple CRUD application? (OK, its effectively functioning as a WPF training project for them but lets pretend it turns into a "real" app).

  • Do you ever think its acceptable to use L2S entities all through your application?
  • How difficult is it (from experience) to refactor to use another persistence framework later?

The way I see it, if the UI layer uses the L2S entities as a simple a POCO (without touching any L2S specific methods) then that should be really easy to refactor later on if need be.

They do need a way to centralize the L2S queries, so some sort of way to manage that is needed, even if they do use L2S entities directly. So in a way we are already pushing toward some aspects of DAL/DAO/Repository.

The main problem with Repo I can see is the pain of mapping between L2S entities and some domain model. And is it really worth it? You get quite a lot "for free" on L2S entities which I think would be hard to use once you map to another model.

Thoughts?

+1  A: 

Basically what we did for a project was that we had a Business layer that did all of the "LINQing" to L2S objects... in essence centralizing all querying to one layer via "Manager Objects" (I guess these are somewhat akin to repositories).

We did not use DTOs to map to L2S; as we didn't feel is was worth the effort in this project. Part of our logic was that as more and more ORMs support Iqueryable and similar syntax to L2S (e.g. entity framework), then it probably wouldn't be THAT bad to switch to a different ORM, so its not that bad of a sin, IMO.

Giovanni Galbo
+1  A: 

Repositories are not a big deal. See here for a pretty good treatment of their use in ASP.NET MVC:

http://nerddinnerbook.s3.amazonaws.com/Part3.htm

Robert Harvey
I think the reason they are not a big deal in that scenario is they are using the L2S entities directly as their "domain" model. Which I suspect is frowned on by quite a few. But its definitely fast to get up and running, and could probably work fine on this project.
Schneider
Whether or not it is appropriate depends on the size of the project. On small projects (I have one with 30 tables in it, and StackOverflow has at least this many), the L2S entities will work just fine.
Robert Harvey
+1  A: 
* Do you ever think its acceptable to use L2S entities all through your application?

Thats depends. If you do a short lived product you can get things easily wired up in a quick succession if you use L2S. But if you do a long lived product which you might have to maintain for a lond duration, then you better think about a proper persistence layer.

* How difficult is it (from experience) to refactor to use another persistence framework later?

If you use L2S in all your layers, well then you must not think about re-factoring them to use another persistence framework. This is exactly the advantage of using a framework like NHibernate or Entity Framework in your persistence layer , that though it requires a bit of extra effort upfront it will be easy to maintain in the long run

Bumble Bee
+2  A: 

The only major drawback to using L2S entities all the way through is that your UI needs to know about and bind to the concrete entities. That means your UI knows your data layer. Not usually a good idea. You really want a layered approach for anything that has the potential to be serious.

That said, it's perfectly possible to use the LINQ-to-SQL entities themselves in a layered architecture without knowledge of the data layer: extract interfaces for the entities and bind to them instead.

Keep in mind that all L2S entities are partial classes. Create interfaces that reflect your entities (Refactor => Extract Interface is your friend here) and create partial class definitions of your entities that implement the interfaces. Put the interfaces themselves (and only the interfaces) in a separate .DLL that your UI and Business Layer reference. Have your Business Layer and Data Layer accept and emit these interfaces rather than the concrete versions of them. You can even have the interfaces implement INotifyPropertyChanging, since the L2S entities themselves implement those interfaces. And it all works peachy.

Then, when/if you need a different persistence framework, you have no pain at all in the BL or UI, only in the data layer -- which is where you want it.

Randolpho
with WPF the UI does not really need to "know" about the concrete entities to any significant extent, thanks to the powerful databinding
Schneider
good idea to work with interfaces, but I wonder in general if there are any pain points building your "model" around the L2S partial classes
Schneider
Well, the first pain point I noticed is that your using statements have to be inside the namespace declaration for the file of the partial class file (usually Foo.cs if your L2S file is Foo.dbml), otherwise the designer breaks and breaks hard. But the biggest pain point is associations; you'll have to build some implementations that cast associated entities to their interface, and creating an association tree/hierarchy can be rough. It's usually best to implement association building *within* your data layer.
Randolpho
Also, you still have to have a reference to the concrete classes, even with WPFs uber-awesome databinding.
Randolpho
A: 

It sounds like you should be considering the ViewModel Pattern for WPF

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

James Fleming