Scaffolding with Entity Framework and the MetadataType attribute


OK, I admit it: I'm an Entity Framework virgin! I do have experience of other ORM tools though – in previous projects I've used LLBLGen quite a bit. More recently, though, I've been dabbling with micro-ORMs such as PetaPoco and MicroLite.

I decided to use EF as part of a really simple proof of concept – scaffolding a simple SQL Server table using ASP.NET Dynamic Data. (It seems like Dynamic Data is out of fashion these days what with MVC, but I remember being blown away by the BLINQ demo back at TechEd2006).

So, I added an ADO.NET Entity Data Model to my project and it generated a class for the database table I want to manage. I then edited the Global.ascx for my Dynamic Data website to use the generated entity and hey presto – a working administration website with Edit / Update / Delete capability. Plus sorting and paging on the List page. Nice.

Now, how to change the column headings on the grid so that they're a bit friendlier? DataAnnotations allow us to set a DisplayName for a property using an attribute. But I don't want to just decorate the generated code – what if I choose to re-generate? I don’t want to have to remember to manually decorate again and again…

Entity Framework sensibly uses partial classes (as does LLBLGen) so that you can keep non-generated code in a separate file. And although you can have partial methods – but not partial properties – so how do you decorate them?

Turns out you decorate the class and point it at another class with identical properties that you can decorate. You use the MetadataType attribute, like so:

    [MetadataType(typeof(Orders_Attributes))]
    public partial class Orders
    {
    }

    public class Orders_Attributes
    {
        [DisplayName("Client Name")]
        public string ClientName { get; set; }

        [DisplayName("Address Line 1")]
        public string Address1 { get; set; }

        [DisplayName("Postcode")]
        public string Zip { get; set; }

        [DisplayName("Item Description")]
        public string ItemDesc { get; set; }
    }

Which is great – and it works!

It doesn't really get around the problem of regenerating the entity – but it moves it elsewhere into a class that's easier to maintain…

Comments