2009-01-13

A DbMetadataProvider for ASP.NET Dynamic Data

I read the article from Marcin on Asp.net on Dynamic Data Futures and custom metadata Providers. I wanted to implement his feature with a database persistance.
For this example, I will store this properties :
  • Name of a table

  • Name of a column

  • Show or not a column


Database structure

The structure is composed of two tables :
  • ST_TYPEOBJET : which store the table attributes : TOBJ_NAME (Name of the table)

  • ST_PROPRIETEOBJET : store the column attributes : PROB_NAME (Name of the column) and PROB_SHOW (Show it Y/N)

ST_TYPEOBJET have a column named T_OBJTYPENAME which store the corresponding Mapping type name (Full Name with assembly)
ST_PROPRIETEOBJET havec a column named PROB_PROPERTYNAME which store the corresponding mapping property.

Implementing a DbMetadataProvider

This DbMetadataProvider is pretty simple. It parse the data in all tables (with LinqToEntities provider), then for each table it register the name with the InMemoryMetaDataManager.
Then, for each property, it register the name and the scaffolding (Show it or not).

///
/// Database metadata Provider
///
public class DbMetadataProvider
{
///
/// Registering metadatas
///
public static void RegisterMetadata()
{
Entities oContext = new DALBase.Entities();
foreach (ST_TYPEOBJET oTypeObjet in oContext.ST_TYPEOBJET.Include("ST_PROPRIETEOBJET"))
{
//Getting the type of the table in the mapping assembly
Type oType = System.Type.GetType(oTypeObjet.TOBJ_TYPENAME);

//Saving the name of the table as attribute
InMemoryMetadataManager.AddTableAttributes(oType,
new DisplayNameAttribute(oTypeObjet.TOBJ_NAME));

foreach(ST_PROPRIETEOBJET oPropriete in oTypeObjet.ST_PROPRIETEOBJET)
{
//Getting the property
PropertyInfo oProperty = oType.GetProperty(oPropriete.PROB_PROPERTYNAME);

//Saving scaffolding
if (oPropriete.PROB_SHOW)
{
//Saving name
InMemoryMetadataManager.AddColumnAttributes(oProperty, new DisplayNameAttribute(oPropriete.PROB_NAME));
}
else
{
InMemoryMetadataManager.AddColumnAttributes(oProperty, new ScaffoldColumnAttribute(false));
}
}
}
}

Call to the provider in global.asax

You just have to specify wich metadataprovider you will use with your model in the global.asax of your web site.
Here, you specify the InMemoryMetadataProvider as the MetadataProviderFactory :
model.RegisterContext(typeof(Entities), new ContextConfiguration()
{
ScaffoldAllTables = true,
MetadataProviderFactory = (type => new InMemoryMetadataTypeDescriptionProvider(type, new AssociatedMetadataTypeTypeDescriptionProvider(type)))
});

Then, you load here all your metadatas :
DbMetadataProvider.RegisterMetadata();

That's it.

kick it on DotNetKicks.com

No comments:

Post a Comment