Obtaining table metadata using Linq to SQL – MappingSource

One of the posts on the MSDN forum asked how to obtain the type length of a column in the table using Linq, this post will just explain how to obtain this information and some information on the MappingSource object.  When linq does the mappings of database to objects, it transforms the DBType (NVarChar) into a CLR Type (String) which means when you are accessing the objects in code, you are accessing them as .Net types hence no simply way to get the underlying DBType.  One way would be to look the information up in the mappings file or the attribute but Dinesh Kulkarni (PM) pointed out an more directly way, in an indirect way.

The DataContext has a property which allows access to all of the mapping information, this property is Mapping.MappingSource.  The MappingSource object has a property GetModel() which requires the type of the DataContext which contains the table as a parameter. This then returns a MetaModel object which allows you to access some high level information. The method we are interested in is the GetMetaType() which accepts the typeof the entity object we are interested in and returns a MetaType object.  This is when it starts to get interesting.  The MetaType holds information about the table such as associations, DerivedTypes and Inheritance information, but the method we are interested in is GetDataMember() which takes a MethodInfo object relating to the column we want information about. This returns a MetaDataMember which holds all the information about the column, such as if it is a primary key, expression, nullable and DBType.

To demonstrate this in code, first we get the MemberInfo type for the column we are interested in for the GetDataMember method.  Then we can gain the DBType via the MappingSource.

string columnName = “OrderID”;
MemberInfo[] mf = Type.GetType(“LinqConsole.Order”).GetMember(columnName);

db.Mapping.MappingSource
                      .GetModel(typeof(DataClasses1DataContext))
                      .GetMetaType(typeof(Order))
                      .GetDataMember(mf[0])
                      .DbType;

Code isn’t that complex, but we can remove the need for obtaining the MemberInfo by going via the DataMembers collection and using a lambda question to return the MetaDataMember for the column name.

string orderIDType = db.Mapping.MappingSource
                                            .GetModel(typeof(DataClasses1DataContext))
                                            .GetMetaType(typeof(Order))
                                            .DataMembers.First(x => x.Name.Equals(columnName))
                                            .DbType;

The DBType in this case is “Int NOT NULL IDENTITY”.  For ShipName it comes out as “NVarChar(40)”.

Note, when using either of these ways you need to check to make sure that the column actually exists and handle situations when it doesn’t correctly.  In this cause, using the first approach might be easier.

Post link:

http://forums.microsoft.com/MSDN/showpost.aspx?postid=1944830&siteid=1

Technorati Tags: ,

Leave a Reply

Your email address will not be published. Required fields are marked *