Projecting Onto a Presentation Model with the Entity Framework and ASP.NET MVC

Posted by on in Blogs
In this post, I will demonstrate how to map entity models to views in an ASP.NET MVC application without worrying about implementation details like eager loading, lazy loading, or having to manually optimize SQL for the task at hand. I will argue that expressing the relationship between an entity model in the presentation model in a LINQ projection is far simpler than other methods of doing this mapping.

Imagine that you've been asked to write a new web application to track employees for a customer, Chotchkies restaurant. The application must use ASP.NET MVC and the ADO.NET Entity Framework. The user interaction designers have mocked up the following interface for editing an employee:

Employee editor

Upon seeing this mockup, your first recommendation is to fire the user interface designers. But management declines to follow your recommendation. So how should you implement this? Since this is a new application, you have no database, no entity model, nothing. Where to begin?

Presentation Models


For a variety of reasons, I always use strongly-typed views in my ASP.NET MVC applications. Also, I use presentation models instead of using entity types directly as the model type for my views.This allows the user interface and data models to evolve independently.

Because I am likely to want to build user interfaces using ASP.NET MVC 2's Dynamic Templated Views, I need to decorate the view model with presentation concerns, like noting that the "Flair count" field is read-only in this particular view.

Especially in view of the less-than-compelling user interface markup, it's important to realize that the design of the user interface is likely to change wildly over the course of implementing the application. When actual users begin to test the application, they will request changes to the user interface, and you need to be able to adapt to this.

This has two important implications: You must get a prototype to testers and end-users as fast as possible, and your user interface must not be deeply coupled to the rest of the application, given the high likelihood of change.

So based upon the user interface prototype above, the following presentation model might be reasonable:



It's now trivial to write an action which can be used to develop a view for editing the employee, and which matches the UI prototype above. Such an action might look like:

Demo employee action code

I'll spare you the HTML. At this point, I have a running application which the user interaction designer can approve, and testers can try out. My total effort, thus far, is a few minutes of work. If I had started by designing a database and the data model, I would still have nothing to show for my efforts.

Entity Model


At some point however, you need to create a database and an entity model. That was, after all, part of the requirements you were given for the application. Knowing that there might be a need to reference people who are not employees, the entity model is going to have to look very different than the presentation model above. After some discussions with the business analyst, you learn that Chotchkies management is very serious about tracking employee flair, so a first attempt at an entity model might look like this:



Now you can generate a database. At this point, you have a presentation model and an entity model, and need only wire them together.

Projection


Taking a collection of instances of one type, and mapping their properties onto a collection of instances of another type is often called mapping or projection. With older ORMs, which have either no or very limited LINQ support, this can be quite tedious, requiring manual code, the use of tools like AutoMapper, and a good deal of thinking about eager loading, lazy loading, and optimizing situations like the fact that we don't actually want to load all of the flair for an employee here; we just need the count.

The Entity Framework, on the other hand, makes this very easy, as we can just express the relationship between the entity model and the presentation model with a LINQ expression:



I'm glossing over some details here. In a real-world application, for example, we would use the repository pattern rather than grabbing the context directly in the controller. But the point of this post is shown in the code above:

By expressing the relationship between the entity model and the presentation model as a LINQ query, it is no longer necessary to worry about implementation details like eager loading versus lazy loading, optimizing the SQL for the Count and avoiding loading big properties not actually used here. All of this can be — and is — derived from the query above, automatically.


Comments

  • Guest
    J.W. Tuesday, 5 January 2010

    Hi, Graig, do you have a sample application that can be downloaded?

    Response: Not yet. Soon, though.

  • Guest
    NW Tuesday, 26 January 2010

    I'm having an issue trying to project on to a presentation model where a parent object has a list of references to child objects. Let's say I have a Parent entity and a Child entity, and in the storage model, each Child has a reference to a single parent. In my presentation model, I want a PresentationParent to have a List. I'm trying to construct this with a query like so:

    from p in entities.Parent
    select new PresentationParent {
    ID = p.ID,
    Name = p.Name,
    Age = p.Age,
    Children = (from c in p.Children
    select new PresentationChild {
    ID = c.ID,
    Name = c.Name,
    Age = c.Age
    }).ToList()
    }


    I get an exception at runtime when I try to enumerate the results that LINQ to Entities "doesn't recognize" the ToList() method. It works fine if I'm using LINQ to SQL. Is there a way to do this using LINQ to Entities?

    Response: Your ToList is in the wrong place. Try:

    from p in entities.Parent
    select new PresentationParent {
    ID = p.ID,
    Name = p.Name,
    Age = p.Age,
    Children = (from c in p.Children
    select new PresentationChild {
    ID = c.ID,
    Name = c.Name,
    Age = c.Age
    })
    }).ToList();


  • Guest
    Jim Reineri Thursday, 6 May 2010

    I just stumbled onto this article and even tho it is over four months old I do have a question/comment.
    Is it not true that it is actually LINQ that is responsible for the ease of creating the projection and not Entity Framework? It seems that LINQ could be used in this way with LINQ to Objects, LINQ to XML etc. Without EF at all.

  • Guest
    Bryce Tuesday, 24 August 2010

    Can you publish the complete script or ap?

  • Guest
    WB Friday, 10 September 2010

    I laughed out loud at the Flair count property.

    It's been a long time since a code snippet has brought a smile to face and I was told I could laugh at a reasonable level in my cube.

  • Guest
    annuaire de casinos Sunday, 26 September 2010

    can u punlish the sample application.

  • Guest
    Ray Akkanson Friday, 9 March 2012

    LinQ is the way. I really like Entity Framework 4.5 version. Makes Linq even more powerful.

    Ray Akkanson

  • Guest
    Lisa Monday, 6 August 2012

    Hello Craig,
    for me your sample code only works for exact this scenario. If you put the linq query in a repository class (which you mentioned at the bottom of your post...) then you can not return the anonymous data with select new. Thus either your repository must fill the query data into the EmployeePresentation object which is bad as a repository should not be coupled to the mvc namespace and there sit the view models... Another Reason/Advantage to use ValueInjector or AutoMapper (which you mentioned) is to write ONE line of code in the controller instead of 5 (You have 5 properties assignments). What do you think Craig?

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: