Tip 40 – How to materialize presentation models via L2E


Problem:

Imagine that you have these entities

public class Product
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual Category Category { get; set; }
}

public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual List<Product> Products { get; set; }
}

But for your UI you want to display the product id, product name and the product’s category’s name.

You might try passing this query to the presentation layer.

var displayData = from product in ctx.Products.Include(“Category”)
                  select product;

But then you are passing more than is required around, and binding the UI tightly to the conceptual model, which is probably a bad idea.

Your next try might be a query like this:

var displayData = from product in ctx.Products
                  select new {
                     ID = product.ID, 
                     Name = product.Name, 
                     CategoryName = product.Category.Name 
                  };

But then you’ll quickly discover you can’t pass the anonymous types to another method, at least not without a nasty hack.

Solution: 

Most people think LINQ to Entities can only materialize Entities and Anonymous types.

But in fact it turns out it can materialize any non-generic class that has a default constructor.

Anyway what this means is you can create a view class like this:

public class ProductView
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string CategoryName { get; set; }
}

And then write this:

var displayData = from product in ctx.Products
                  select new ProductView {
                     ID = product.ID, 
                     Name = product.Name, 
                     CategoryName = product.Category.Name 
                  };

And then pass this to your view without any problems at all.

I only just found out about this myself, I had always assumed this would fail.

So this was a nice pleasant surprise.

Comments (5)

  1. Craig Stuntz says:

    I have several examples of projection onto Presentation Models (plus some thought into how to handle data coming in) in this presentation:

    http://blogs.teamb.com/craigstuntz/2009/09/11/38394/

    I’m thinking of putting up a demo app for using repositories, presentation models, and the EF with ASP.NET MVC.

  2. Alex D James says:

    @Craig,

    Cool. Thanks for the link, I’m sure people reading my blog will find it interesting. Let me know if/when you do the demo app, I will definitely link to it.

    Alex

  3. mcsean says:

    Yes, I do. Great presentation Craig! yeah, hope to see your demo too!

  4. Anonymous says:

    A demo app is in the works, but for the time being here’s a post which elaborates on the above:

    http://blogs.teamb.com/craigstuntz/2009/12/31/38500/

  5. Anonymous says:

    There's nothing special about what select does, you can just as easily do

    class Wtf {

     public Wtf(int i, string s) {}

    }

    var w = from row in something

           select new Wtf(1, "hello")