6
votes

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.

3

3 Answers

4
votes

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.

3
votes

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.

0
votes

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