Database First and View Models

五迷三道 提交于 2019-12-13 07:28:50

问题


I have little experience with Database First Models and how to approach these with MVC View Models.

It is clear I cannot change the original model but I would like to add some annotations to the model for validation purposes.

Therefore what I tried to do was create a ViewModel which inherits from the entity

My DB First generated model - do not amend

public partial class xmldata
{
    public string ISBN { get; set; }
    public string title { get; set; }
    public string blurb { get; set; }
    ...
}

I then created a view model as follows which inherits from xmldata

public class XmlDataViewModel : xmldata
{
    [AllowHtml]
    [Display(Name = "Blurb")]
    public string BlurbVm {
        get { return blurb; }
        set { blurb = value; }
    }
    ...
}

The field shown above I needed to AllowHtml and my best solution so far but however in the controller actions I have still had to manually map the BlurbVm field back to blurb even though i would of thought the setter above would of handled that (im using Automapper for the rest of the fields) so I am confused as to why this didn't work.

Also at the moment I am doing Validations in the controller and may want to refactor this later to move them into the View Model so I can use the [Required] annotation and also [Display (Name="Title")] fields which are currently handled in the view.

Probably my overall question here is am I using the best strategy for dealing with Model Annotations and view models when using a Database First Model.


回答1:


I thought I might add some detailed explanation on why data model is different from view model

Difference between model and view model

You are mixing two different things, as @Stephen Muecke mentioned in comments. View model serves one purpose - take data from controller and transfer it to to view. In complicated cases data you want to show the user is completely different from what your database looks like. To represent your data structure in your code you use data model. It has exactly the same properties as you have in your database.

However view model shouldn't know about how your data is structured. You just simply assign its properties and pass those data to the view.

Consider following example. You have Customers and Orders tables in your database.

Customers:

ID | Firstname | Lastname

Orders:

ID | Amount | CustomerID

In order to map those data in your code you would have to create two classes

public class Customer
{
    public int ID { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

public class Order
{
    public int ID { get; set; }
    public decimal Amount { get; set; }
    public int CustomerID { get; set; }
}

But in your application you have some view, where you want to display customers first names and total amount they've spent in your shop. You could create view model, which will serve exactly this purpose.

public CustomersViewModel
{
    public string Firstname { get; set; }
    public decimal TotalAmount { get; set; }
}

See how different this view model is, compared to your data model? It doesn't know about ID value nor about Lastname.

This model is used only to display your data properly, so here you can use all DataAnnotations you want.

public CustomersViewModel
{
    public string Firstname { get; set; }

    [DisplayFormat(DataFormatString="{0:#.####}")]
    public decimal TotalAmount { get; set; }
}

Why on MSDN they're annotating data models?

Because like @CodeCaster mentioned - it's bad practice, but it's not forbidden. If your application is really simple, you can skip view models altogether! Is it a bad idea? Yes - even in simple cases you should use dedicated view models, because it costs you nothing, but decouples your views from your data structure. I guess they didn't want to complicate those examples, so when reading this tutorials you should focus only on how to use DataAnnotations.

How to bind custom view model in your controller?

Usage of view models is not limited to returning them to views in order to simply display some data. You can use them, if you want to pass data for the user to modify it. It is absolutely acceptable to have view model, which have exactly the same properties as your data model. Considering previous example, we could have CustomerViewModel which we can use in EditCustomer.cshtml view.

In this view we could have our edit form looking like this

@model CustomerViewModel

// HTML markup
@Html.LabelFor(m => m.Firstname)
@Html.TextboxFor(m => m.Firstname)
// another properties similar

If our Edit method in CustomerController would look like this

public Edit(CustomerViewModel customer)

there is not much we have to do more. ASP.NET will automatically bind posted form with customer of type CustomerViewModel. Now we only have to pass data stored in customer into appropriate data model and save it in database.




回答2:


You can add data annotation to your main domain model. While creating manual data annotation ensure that namespace are equal with generated class's namespace.

[MetadataType(typeof(XmlDataDataAnnotation))]
public partial class xmldata{ }

public class XmlDataDataAnnotation
{
  [AllowHtml]
  [Display(Name = "Blurb")]
  public string blurb { get; set; }
}

Then you can create complex property in your view model.

public class XmlDataViewModel
{
  public xmldata XmlData {get;set;}
}

Also please see below link for clarification:

Add data annotations to a class generated by entity framework

Data Annotations with Entity Framework 5.0 (database first)



来源:https://stackoverflow.com/questions/39995841/database-first-and-view-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!