Suppose you have a database first approach when building a web application. If your database changes often and you need to regenerate the model class, you will lose all of the attributes you had already applied to the model class such as the ones for validation, label names etc. This approach can be very inefficient and you can lose important attributes of your fields.

We can prevent this problem by creating a separate metadata class that contains the attributes with the help of a partial class. Then using the MetadataType attribute we can associate the model class to the metadata class. With that, the attributes from the metadata class will be applied to the model class generated by the database tool. Doing this, the model class can be regenerated as often as we like and the attributes that have been applied to the metadata class will always be preserved.

For example:

Suppose we have a model class MyPage that is generated through database-first approach.

//-------------------------------------------
// 
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// 
//-------------------------------------------
namespace Test.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class MyPage
{
public long ID { get; set; }
public string Title { get; set; }
public string Url { get; set; }
}
}

Then we create a new class called MyPageMetaData as well as a partial class for the existing MyPage class.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Test.Models {
public class MyPageMetaData {
[Required]
[Display(Name ="Page Title")]
public string Title { get; set; }
[Required]
[Display(Name = "Page Name Url")]
[RegularExpression("^[a-z0-9-_]+$",ErrorMessage="Please use [a-z,0-9] or '-' or '_'")]
public string Url { get; set; }
}

[MetadataType(typeof(MyPageMetaData))]
public partial class MyPage {
}
}

The first class is called MyPageMetaData which contains the properties like Title and Url to which we add attributes like [Required] or [Display]. These attributes will stay here as long as we don't manually remove them and they will apply to the properties above which they appear.

The second class is the MyPage partial class which as you can see has the [MetadataType] attribute above it which in itself contains the name of the previous class, MyPageMetaData. This partial class, MyPage, extends the original class MyPage which was generated by the database tool.

This piece of code, [MetadataType(typeof(MyPageMetaData))], tells the compiler that the class MyPageMetaData contains additional data for the MyPage class and use that data whenever the MyPage class is used.

 You can read more about this attribute on the MSDN documentation page.

Written by: Mite Tashev