Thursday, 6 August 2009

ASP.NET Dynamic Data - Generate the Metadata Classes from Entity Framework Quickly

Problem:
It's time-consuming to write the metadata classes for your entity framework assuming you have many classes.

Solution:
Run my following class using
EFMetadataGenerator.Generate( "MIPortalModel" ,@"c:\MIPortalEntities.cs");

Then all the metadata classes including their properties will be generated for you.
using System;
using System.Linq;
using System.Reflection;
using System.Text;

/// <summary>
/// Summary description for EFMetadataGenerator
/// </summary>
public class EFMetadataGenerator
{
/// <summary>
/// </summary>
/// <param name="fromNamespace">This is the namespace of your EntityFramework</param>
/// <param nam/// </summary>e="toFile">This is the path of the file on which you want the results to be saved</param>
public static void Generate(string fromNamespace, string toFile)
{
var result = new StringBuilder();
result.Append(AddHeader(fromNamespace));
var modules = Assembly.GetExecutingAssembly().GetModules();
foreach (var module in modules)
{
var types = module.GetTypes().Where(t => t.Namespace == fromNamespace);
foreach (var type in types) {
result.Append(GenerateMetadataClasses(type));
}
}
result.Append(AddFooter());
System.IO.File.WriteAllText(toFile, result.ToString());
}

private static string AddHeader(string namespaceName)
{
var sb = new StringBuilder();
sb.Append("using System;" + GetNewLine(1));
sb.Append("using System.ComponentModel;" + GetNewLine(1));
sb.Append("using System.Data;" + GetNewLine(1));
sb.Append("using System.Data.Objects;" + GetNewLine(1));
sb.Append("using System.ComponentModel.DataAnnotations;" + GetNewLine(1));
sb.Append(GetNewLine(1) + "namespace " + namespaceName + GetNewLine(1)); sb.Append("{" + GetNewLine(1));
return sb.ToString();
}

private static string AddFooter() { return "}"; }

private static string GenerateMetadataClasses(Type type)
{
var className = type.Name;
var metadataClassName = type.Name + "_MD";
var sb = new StringBuilder();
sb.Append(GetTab(1) + "#region " + className + GetNewLine(2));

// generate the partial class
sb.Append(GetTab(1) + "[MetadataType(typeof(" + metadataClassName + "))]" + GetNewLine(1));
sb.Append(GetTab(1) + "public partial class " + className + GetNewLine(1));
sb.Append(GetTab(1) + "{" + GetNewLine(1) + GetTab(1) + "}" + GetNewLine(2));
// generate the metadata class
sb.Append(GetTab(1) + "public class " + metadataClassName + GetNewLine(1));
sb.Append(GetTab(1) + "{" + GetNewLine(1));
var properties = type.GetProperties();
foreach (var propertyInfo in properties)
{
sb.Append(GetTab(2) + "public object " + propertyInfo.Name + " { get; set; }" + GetNewLine(1));
}
sb.Append(GetTab(1) + "}" + GetNewLine(2));
sb.Append(GetTab(1) + "#endregion " + className + GetNewLine(2));
return sb.ToString();
}

private static string GetNewLine(int count)
{
var sb = new StringBuilder();
for (var i = 0; i < count; i++) sb.Append("\r\n");
return sb.ToString();
}

private static string GetTab(int count)
{
var sb = new StringBuilder();
for(var i = 0; i< count; i ++) sb.Append("\t");
return sb.ToString();
}
}

No comments: