Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework and the relationship with MVC

I am trying to understand the whole MVC/EF relationship. If I create a Entity Model that would only interact with the database (since you shouldnt pass you entity model to a view), then a class for the Model, and finally a view model all shown below. My only question is it seems redundant to have the second class, the only different in the examples I have seen is that they apply data annotations to that class since it is interacting with the view. Why is it so important to make sure that entity objects arent exposed at the view layer?

I havent actually started writing a project yet, but I assume that you would use the Entity model for interacting with a database then cast it into a ProductModel to pass to the view is this the correct logic?

Entity Model:

public class Product 
{
    [Key()]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
}

Model:

public class ProductModel
{
    public int ID { get; set; }
    [StringLength(50)]
    [Required(ErrorMessage = "Product Name is required.")]
    [Display(Name = "Product Name")]
    public string Name { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
}

ViewModel:

public class ProductViewModel
{
    Product myProduct { get; set; }\
    //Plus any other properties I may need for the view.
}

UPDATE:

In the example I have been reading they also have a DBContext set as follows. So is the ProductModel class useless then?

public class MyAppContext : DbContext
{
    public MyAppContext()
        : base("name=DBConnection")
    { 
    }

    public DbSet<Product> Products { get; set; }

 }
like image 885
user2220986 Avatar asked Mar 28 '13 18:03

user2220986


4 Answers

There's times, and particularly on simple models, where a view model may not be required. But, and a big "but", I've found very few instances of that situation and even then, I later generally find a need to go back and create a view model, anyways. Having a specialized view model is safer, simpler and easier all-around.

You might look at it as extra work, but think of it in terms of separation of concerns (which is the whole point of MVC). If I want to present a SelectList for an input, for example, I can either add it to ViewBag or to my model. If I add it to ViewBag, I lose strong-typing which is never ideal, but it doesn't belong on my database-tracked entity, either. Having a view model let's me put this information exactly where it should go: a strongly-typed model that exists to serve the view and only to serve the view.

Or, consider validation: what if I want a field required for the database (non-null), but I want to make this optional for the user, and fill it with some business logic myself behind the scenes if the user opts not to specify. The view model can handle that abstraction easily whereas adding it to the entity, itself, would add a huge layer of complexity.

Nothing is required, of course. You can always set up your project however you like, but best-practices are best-practices for a reason: developers just like you, time and again, have ran into the same issues and coalesced around a workable solution. You might be able to avoid view models for a time, but eventually, you'll run into the same roadblocks and incorporate them anyways, so just do it right from the start and make your life easier.

like image 154
Chris Pratt Avatar answered Sep 30 '22 14:09

Chris Pratt


There are two major reasons I create a model class, separate from my entity.

  1. As you mentioned, attributes. You may want to reuse your entities in several applications and they may not use the same attributes. You don't want to pollute your entities with these.

  2. Depending on them ORM, your entities may require a base class. Or there might be attributes, or other customizations that you have to apply to the entities. This could cause there to be difficulties when testing your Business Logic. Additionally, if you change ORMs or something in your ORM changes, you will keep that change isolated from the rest of the application.

Basically, you are isolating the different layers of your application and protecting one layer from changes made in another.

like image 33
cadrell0 Avatar answered Sep 30 '22 12:09

cadrell0


You need Product class, ProductViewModel class then your DbContext. If you are doing this for the first time, read Pro ASP.NET MVC 3 Framework, Third Edition

or

Pro Asp.Net Mvc 4

They have a detailed information about MVC and both books have a Real Application tutorial you can follow from start to finish including deployment.

You will also learn about Unit Testing and other MVC tools such as Dependency Injection (Ninject) and Moq

like image 23
Komengem Avatar answered Sep 30 '22 13:09

Komengem


In Addition to the answers above, another point that hasnt been mentioned to to prevent data being sent to the view/client that doesnt need to be.

for example suppose your product model contains the price you pay your supplier to purchase the product. you dont want your customers to see this data, but if it is included in the model sent to the view - even if you don't display that field - they can assess it. this is a case where you would use a different view model and copy the data from the ef/database model to the view model before sending it to the view.

sometimes you can end up with a DBcontext class, an EF/database class/Model and several viewmodels each holding a different subset of the data from the database model.

you can also find yourself with a viewmodel that holds data from several Database models, you offten see this where the view uses lists or dropdowns as an alternative to sending the list options in the viewbag.

like image 32
Stuart Avatar answered Sep 30 '22 12:09

Stuart