Search code examples
c#asp.net-mvcentity-frameworkedmxedmx-designer

Adding attributes to EF6 generated entity classes


I am using EF6 in a database first context. In this case I am using the entity classes in my MVC web project and would like to annotate the entity's fields with various validation and display attributes. However, when I refresh the entity classes by doing an update from database in my edmx designer, the classes regenerate and my attributes are lost.

What is the best approach to getting round this?


Solution

  • When working with generated entity classes in a database first Entity Framework project, it is often necessary to apply attributes to the class’s fields. This is especially the case if you are foregoing the use of ViewModels and using your entities directly in an MVC web project.

    Of course if you were to apply validation or display name attributes to the fields directly, the next time the data model is generated due to an upgrade from database action, these would all be overwritten.

    Luckily the classes generated by Entity Framework are marked as partial. This means that we can create a second class that augments the first. Effectively the two classes are seen as one. For example:

    [MetadataType(typeof(AnimalMetaData))]
    public partial class Animal
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public int NumberOfLegs { get; set; } etc..
    
    
    public class AnimalMetaData
    {
        [MaxLength(200)]
        [Required]
        public string Name { get; set; }
    
        [MaxLength(1000)]
        public string Description { get; set; } etc...
    

    But of course we have a problem here. We have put the attribute to associate the metadata class on the entity class and this will be overwritten on an update from the database. So how do we get round this? Simple! We create a third ‘dummy’ class called Animal that sits alongside the metadata class and is also partial:

    [MetadataType(typeof(AnimalMetaData))]
    public partial class Animal {}
    

    We annotate this class with our metadata class, so in effect we have the three classes acting as one; the entity itself, the dummy class to link the entity with the metadata definition class.

    For the sake of keeping things tidy, you could do worse than to place the metadata and dummy classes together in a separate folder adjacent to the entities generated by Entity Framework.