6

I'm working on a one-man ASP.NET MVC 3 project (I have complete control over database schema and code), and I'm trying to decide between going database-first and POCO w/ my EF4 models, or if I should go w/ code-first.

The main thing I'm trying to achieve is decorating my models with DataAnnotation attributes so that I can enforce schema validation prior to doing any persistence. Looking at Scott Guthrie's article about model validation w/ MVC 2, he talks about article about doing it with code-first (Step 2), and doing it with model-first (or database-first) using "buddy classes" (Step 5).

I historically have done my database design using the SQL Server designer GUI (and scripts), so I'm definitely more productive with that, strictly when it comes to database design. However, unless I ditch the idea of decorating my models w/ DataAnnotation attributes for validation, I will be violating DRY by not only having model properties in two classes, but having to, in essence, build my schema in two places.

I'm looking for anyone that's had experience with both methods (or even one method), and can offer feedback on which way they went, why they decided that, and how they found it to work. I'd also like to know if I might be better off going a completely different, using tools like Fluent Validation, or maybe even abandoning domain model-level validation altogether, and keeping my validation in the services and view models.

рüффп
  • 5,172
  • 34
  • 67
  • 113
Jerad Rose
  • 15,235
  • 18
  • 82
  • 153

3 Answers3

4

Firstly Code First is in CTP and therefore doesn't have a go-live licence. If this is a project to be delivered in the next couple of months then the decision is Model first.

Having said that, Code First classes using DataAnnotations are cleaner than Model First POCO with buddy classes but the most important thing in my experience is explicit intent. As long as your design is clear and most importantly consistent either approach is suitable.

For a small project (i.e one man as you've stated) I'd say you're likely to be more productive with Model First and designing through an edmx. This will also feel more comfortable for you coming from a schema first background. There are however a number of hoops you'll need to jump through to get the POCO classes working nicely such as installing the POCO T4 template then modifying the T4 template created in your project to pull the POCO's into a separate assembly. You don't want them in the DAL assembly which is where they will start off. You're then left with the decision of how comfortable you are with partial classes for implementing DataAnnotations; for reasons I don't agree with many people see these as poor design.

In an MVC project you'll hit the ubiquitous DRY problem using DataAnnotations with either approach when you decide to use ViewModels. At this point you'll suddenly realise that extensive annotation of your Model for validation is only useful if you are happy sending these classes directly to the view. If you decide to keep the views lightweight and use ViewModels you have to repeat the DataAnnotations on the ViewModel otherwise you're left with validation errors at the model level but no way of getting this into ModelState other than manually adding. Neither code first or model first solve this problem as yet so you need to design accordingly. We personally went with a mix and accepted a level of breaking DRY.

Darren Lewis
  • 8,338
  • 3
  • 35
  • 55
  • Thanks, this articulated very well what I was trying to get a better understanding of. While I love the power and flexibility all of these options give us, it still is unfortunate that we often end up having to compromise one thing to gain another. I just need to figure out which one will drive me less crazy before it's too late to change it back. :) – Jerad Rose Mar 01 '11 at 16:01
  • Happy to help Jerad. If you go Model first there is a T4 template available to take your edmx model and create Code First classes from it. Yet another option, sorry! I haven't actually used this template myself yet so perhaps take a quick look before making a final decision either way. http://weblogs.asp.net/jgalloway/archive/2011/02/24/generating-ef-code-first-model-classes-from-an-existing-database.aspx – Darren Lewis Mar 01 '11 at 18:27
3

What type of validation are you looking for? Do you want to inject user input validation rules into entities or do you want validation layer just on top of database operations?

There is a lot of purist discussion that entities should not contain validation attributes because you will never use them in Views - you will use special type of view model classes and validation parameters will be directly on properties of that classes. For medium and large projects I agree. For simple data management projects wich are more like forms over data (just CRUD operations) I disagree because it is additional complexity which you don't need.

EF Code first introduces data annotations used as DB layer validation (btw. data layer validation can be completely different from ui validation). I tried exactly the same approach with EDMX file before this feature was introduced in Code first. You can define validation attributes for classes generated by EF T4 POCO template as well. Problem with my implementation of validation (based on reflection) was that if I performed a lot of updates and inserts it was extremely slow - I haven't compare it to code first yet.

Edit:

Based on current announcement in ADO.NET team blog next EF release (RC planned to end of March) will support validation in all three approaches - Code first, Database first, Model first. I'm still not sure if it means supporting validation in both DbContext and ObjectContext based implementations.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Yeah, I'm mainly looking for validation layer on top of database operations. As you said, I plan to have separate validation attributes on my view models for UI validation, which may or may not be the same as my domain model validations. Basically, I want my service and domain layers to be self-sufficient, and be able to properly handle validations at the service level, rather than assuming the service consumers already did validation. So there are actually a few things I'm trying to figure out, and have been reading several posts on the subject, but having a hard time finding a consensus. – Jerad Rose Mar 01 '11 at 15:17
  • There is probably no consensus at the moment because out of the box validation functionality can use `DataAnnotations` in MVC and now in `DbContext`. If you want to run validation elsewhere you can find different problems - I constructed my solution by reading several blogs about this. – Ladislav Mrnka Mar 01 '11 at 15:27
  • Yeah, that's what I'm figuring out, the more I dig. I've been reading blog after blog, myself, as well as pouring through questions on SO, and with regard to this, there is no perfect solution. Thanks for your help. – Jerad Rose Mar 01 '11 at 16:05
0

You aren't really validating DRY here. The concept of DRY is a bit more nuanced than simple duplication of code. There are acceptable tradeoffs, especially when coupling concerns are taken into account.

When people ask this question, which is quite often if you search around, I usually refer them to the DDD concept of [bounded concepts][1]. Using [Remote] and forcing DRY when it comes to validation tends to bunch up tons of concerns in one place and merging the responsibilities of several layers. Business Logic vs. Persistence and Data Integrity Logic ( non nulls ).

@Darin Dmitrov says it pretty well in a lot of his answers he's made to this exact question. Validating that a required field is filled in is much different from making sure Sally has enough credit to make a purchase and should be treated much differently.

Copied from here: MVC 3 and DRY custom validation

Community
  • 1
  • 1
John Farrell
  • 24,673
  • 10
  • 77
  • 110
  • Thanks, jfar. I'm sorry though, as I have to downvote this, mainly because you're not really addressing my main question. The issue of DRY isn't the main reason for this post, just a small part of it. I'm looking for a comparison of using code-first vs. model-first, and what the various trade-offs are with and without regard to model validation. – Jerad Rose Mar 01 '11 at 05:38
  • @Jerad Rose - Understood, just trying to remove DRY from the conversation. – John Farrell Mar 01 '11 at 14:07
  • No problem, I probably need to dig more into understanding DRY. To me, I always thought this meant that if you had any sort of logical redundancies, this is a violation of DRY. But it sounds like you're saying this isn't always the case, so I need to figure out when it's acceptable/not really violating DRY. Any good articles you recommend that might help me understand this better? – Jerad Rose Mar 01 '11 at 15:05