Search code examples
asp.netentity-frameworkpoco

How to make changes in POCO file in Entity Framework so changes are retained


I am using Database First approach in Entity Framework. I have a table which contain one field called CustomerName and it is NOT NULL.

The generated POCO is given below.

public partial class Customers
{
   public string CustomerName {get; set;}
}

I have two questions.

How can I make this a required field so my code would become like this (shown below). As you know POCO is automatically generated so after I do this and update model from database, all my code is removed.

public partial class Customers
{
   [Required]
   public string CustomerName {get; set;}
}

Second question is why EF automatically doesn't apply [Required] with this field when generating code? The field is NOT NULL in database so shouldn't this be done automatically without having to manually write [Required]?


Solution

  • Here's the answer if you're using EF6:

    Notice that the generated Customers class is partial, we're going to leverage that. First, we'll need to create a new Customers partial class with the exact same name within the exact same namespace:

    namespace WebApp.TheSameNamespaceAsTheGeneratedCustomersClass
    {
        public partial class Customers
        {
        }
    }
    

    Now both of these partials make up the same class it's just that the source code of this class is now split in different files, one of which is generated by the tool and one that you wrote by hand. The difference of course is that you can change the latter without it getting rewritten all the time.

    Note that the namespace has to match but the folder that contains the class file doesn't.

    Now we need to create the metadata class that contains all the necessary attributes and decorate our Customers partial with it, like so:

    namespace WebApp.TheSameNamespaceAsTheGeneratedCustomersClass
    {
        [MetadataType(typeof(CustomersMetadata))] //decorating the entity with the metadata
        public partial class Customers
        {
        }
    
        public class CustomersMetadata //metadata class
        {
           [Required] //your data annotations
           public string CustomerName { get; set; } //the property name has to match
        }
    }
    

    and that's it.

    Is it verbose? Yeah, but that decision was made when db first was chosen.

    A word of caution:

    If you're doing this to use entity classes as data models in MVC, generally speaking, that's considered a bad practice. The recommended way is to create separate model classes and map data from and to entities. There are some security reasons for that, which you should research before you make the final decision.