开发者

How to share DataAnnotations between EF CodeFirst Poco classed and ViewModel classes in MVC?

I am using EF-CodeFirst to create the database from my Poco objects and their configuration. I have heavily used Dataannotation (Required, DataLength, RegularExpression, DataType) to get metadata to MVC and have the error messages pointing to a ressource to localize them later.开发者_开发技巧

For simple CRUD operations this is not a problem.

But as soon as I have the need for ViewModel classes I loose the Dataannotations from my Poco objects.

How can those 2 designs be combined without having to hurt the DRY (dont repeat yourself) principle?

Thanks Andreas


Those two designs can't and shouldn't be combined. Your view models are tied to the views so personally I redefine all the necessary attributes on my view models and believe it or not I don't care about DRY in this case. I do this because the requirements of my views change quite often (yeah customers are capricious) whereas I reuse always the same domain models. For me a view should never know about the existence of a domain model. A view should be dummy and all that it should know about is the view model which is passed to it by the controller.

I know that there are people who might think different and I respect their opinion. So by saying this I am only exposing my personal point of view and my way of working with ASP.NET MVC. And to be quite honest with you my models are POCO objects without any DataAnnotations so I don't encounter such problems. I use DataAnnotations on my view models only for formatting purposes (stuff like DataType, DisplayName and DisplayFormat) and no validation attributes. I use FluentValidation.NET for this purpose.


You can accomplish what you're asking pretty easily. Darin has a very valid point that applies well to larger projects, but I think for the smaller projects it sounds like overkill. It also seems like it depends a great deal on whether you're using DataAnnotations for validation or using a 3rd party library. The repitition involved in not doing this would make for quite a maintenance nuisance, IMHO. There's also the fact that you spend a lot of lines of code just copying data from the DB to the view model; ORMs are supposed to help eliminate that, but so far the solution doesn't appear very good.

Here's an example snip of code on how to do what you want. The first class is partial, with the main body being in the EF generated code (I'm going model first, not code first). Also, as an example, Question has a FK to QuestionGroup. In the DB this is a column named GroupID, but in the ViewModel there's a property named GroupName for displaying in a nice little grid (Telerik Grid, actually, which basically breaks if you try to pass in an EF object).

[MetadataType(typeof(QuestionMetadata))]
public partial class Question
{
}

public class QuestionMetadata
{
    public Int32 ID { get; set; }

    [Required]
    [Display(Name="Question")]
    public String QuestionText { get; set; }

    [Display(Name = "Order")]
    public Int16 SortOrder { get; set; }
}

[MetadataType(typeof(QuestionMetadata))]
public class QuestionViewModel
{
    /* Fields found in the original model */

    public Int32 ID { get; set; }

    public String QuestionText { get; set; }

    public Int16 SortOrder { get; set; }

    /* Fields that map child object data for this view model */

    [Display(Name = "Question Group")]
    public String GroupName { get; set; }
}

IMHO both EF and Telerik are forcing me to not be very DRY here, but there's nothing I can do. EF should be generating these DataAnnotations by default (or at least have the option), since it obviously knows which fields are required (not null) or what the max length of various strings are. Then Telerik forces me to create the ViewModel, which is also painful.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜