4

How can I list columns' metadata (IColumnMetadata) of a table using NHibernate on "any" database?

ITableMetadata contains just GetColumnMetadata() where I need to provide a columnName. IDataBaseSchema contains GetColumns() that returns plain DataTable. I have found method GetColumnName() on AbstractTableMetadata that could use, but it is protected and not contained in ITableMetadata. Any reason for that?

How this API is intended to be used?

TN.
  • 18,874
  • 30
  • 99
  • 157

2 Answers2

0

You are right. ITableMetadata does not expose the names of the columns in the table. It seems that the classes were designed to be used with mapping files where column names are explicitly given. However, if you take quick peek using Reflector, you will find that all the column names are actually stored in a private variable in the AbstractTableMetadata class (of which all implementations of ITableMetadata derive.

Here is the code to retrieve all column names from all tables in the database:

var dialect = sess.GetSessionImplementation().Factory.Dialect;                               
var dbSchema = dialect.GetDataBaseSchema(sess.Connection as DbConnection);               

foreach (DataRow row in (sess.Connection as DbConnection).GetSchema("Tables").Rows)
{
    ITableMetadata md =  dbSchema.GetTableMetadata(row, false);
    var hiddenColumnsProperty = typeof(AbstractTableMetadata).GetField("columns", BindingFlags.NonPublic | BindingFlags.Instance);
    var columns = hiddenColumnsProperty.GetValue(md) as Dictionary<string, IColumnMetadata>;                  

    foreach (var colName in columns.Keys)
    {
        Console.WriteLine(md.Name+"."+colName);
    }
}
stitty
  • 972
  • 9
  • 10
  • Thank you, my question is not about how to use reflection. Since the project is open-source I can just change the visibility or interfaces instead. I want to know whether there is an alternative API for that (that I may have not found). – TN. Dec 02 '14 at 10:01
0

Presumable you can use the Configuration.ClassMappings to get a list of Classes mapped. Each of those will have a Table property, which in turn has a ColumnIterator property. You should be able to get a list of column names from that.

Vadim
  • 17,897
  • 4
  • 38
  • 62
  • This depends on the class mapping. I would like to list columns from the database, not from the mapping. (I am implementing a class mapping generator.) – TN. Nov 29 '11 at 07:30