Add data annotations to a class generated by entity framework

I have the following class generated by entity framework:

public partial class ItemRequest
{
    public int RequestId { get; set; }
    //...

I would like to make this a required field

[Required]
public int RequestId { get;set; }

However, because this is generated code this will get wiped out. I can't imagine a way to create a partial class because the property is defined by the generated partial class. How can I define the constraint in a safe way?


Solution 1:

The generated class ItemRequest will always be a partial class. This allows you to write a second partial class which is marked with the necessary data annotations. In your case the partial class ItemRequest would look like this:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models 
{
    [MetadataType(typeof(ItemRequestMetaData))]
    public partial class ItemRequest
    {
    }

    public class ItemRequestMetaData
    {
        [Required]
        public int RequestId {get;set;}

        //...
    }
}

Solution 2:

As MUG4N answered you can use partial classes but will be better use interfaces instead. In this case you will have compilation errors if EF model doesn't correspond to validation model. So you can modify your EF models without fear that validation rules are outdated.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace YourApplication.Models
{
    public interface IEntityMetadata
    {
        [Required]
        Int32 Id { get; set; }
    }

    [MetadataType(typeof(IEntityMetadata))]
    public partial class Entity : IEntityMetadata
    {
        /* Id property has already existed in the mapped class */
    }
}

P.S. If you are using project type which is differ from ASP.NET MVC (when you perform manual data validation) don't forget to register your validators

/* Global.asax or similar */

TypeDescriptor.AddProviderTransparent(
    new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(IEntityMetadata)), typeof(Entity));

Solution 3:

I found a solution like MUG4N's answer, but instead, nesting the MetaData class within the entity class, thereby reducing the number of classes in your public namespace list, and eliminating the need to have a unique name for each metadata class.

using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models 
{
    [MetadataType(typeof(MetaData))]
    public partial class ItemRequest
    {
        public class MetaData
        {
            [Required]
            public int RequestId;

            //...
        }
    }
}