NHibernate Metadata

I know that O/RMs like NHibernate are supposed to shield us from the gory database internals such as tables, views, columns and such; however, at times, I do have the need to know how my domain model translates to the database. NHibernate, of course, provides us with the information we need, but it isn’t always easy to find, so I wrote my own extension methods for ISessionFactory that allow me to get the metadata I need in an easy way:

   1: public static IEnumerable<PropertyInfo> GetComponents(this ISessionFactory sessionFactory, Type entityType)
   2: {
   3:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
   4:     IClassMetadata metadata = sessionFactory.GetClassMetadata(entityName);
   5:  
   6:     for (Int32 i = 0; i < metadata.PropertyTypes.Length; ++i)
   7:     {
   8:         IType property = metadata.PropertyTypes[i];
   9:  
  10:         if (property is ComponentType)
  11:         {
  12:             String propertyName = metadata.PropertyNames[i];
  13:             yield return (entityType.GetProperty(propertyName));
  14:         }
  15:     }
  16: }
  17:  
  18: public static IEnumerable<PropertyInfo> GetUserTypes(this ISessionFactory sessionFactory, Type entityType)
  19: {
  20:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
  21:     IClassMetadata metadata = sessionFactory.GetClassMetadata(entityName);
  22:  
  23:     for (Int32 i = 0; i < metadata.PropertyTypes.Length; ++i)
  24:     {
  25:         IType property = metadata.PropertyTypes[i];
  26:  
  27:         if (property is CustomType)
  28:         {
  29:             String propertyName = metadata.PropertyNames[i];
  30:             yield return (entityType.GetProperty(propertyName));
  31:         }
  32:     }
  33: }
  34:  
  35: public static IEnumerable<PropertyInfo> GetProperties(this ISessionFactory sessionFactory, Type entityType)
  36: {
  37:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
  38:     IClassMetadata metadata = sessionFactory.GetClassMetadata(entityName);
  39:     
  40:     for (Int32 i = 0; i < metadata.PropertyTypes.Length; ++i)
  41:     {
  42:         IType property = metadata.PropertyTypes[i];
  43:  
  44:         if (!(property is OneToOneType) && !(property is ManyToOneType) && !(property is ComponentType))
  45:         {
  46:             String propertyName = metadata.PropertyNames[i];
  47:             yield return (entityType.GetProperty(propertyName));                    
  48:         }
  49:     }
  50: }
  51:  
  52: public static IEnumerable<PropertyInfo> GetAssociations(this ISessionFactory sessionFactory, Type entityType)
  53: {
  54:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
  55:     IClassMetadata metadata = sessionFactory.GetClassMetadata(entityName);
  56:  
  57:     for (Int32 i = 0; i < metadata.PropertyTypes.Length; ++i)
  58:     {
  59:         IType property = metadata.PropertyTypes[i];
  60:  
  61:         if (property is OneToOneType)
  62:         {
  63:             String propertyName = metadata.PropertyNames[i];
  64:             yield return (entityType.GetProperty(propertyName));
  65:         }
  66:         else if (property is ManyToOneType)
  67:         {
  68:             String propertyName = metadata.PropertyNames[i];
  69:             yield return (entityType.GetProperty(propertyName));
  70:         }
  71:     }
  72: }
  73:  
  74: public static PropertyInfo GetIdentifier(this ISessionFactory sessionFactory, Type entityType)
  75: {
  76:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
  77:     AbstractEntityPersister persister = (sessionFactory as ISessionFactoryImplementor).TryGetEntityPersister(entityName) as AbstractEntityPersister;
  78:  
  79:     if (persister != null)
  80:     {
  81:         return (entityType.GetProperty(persister.IdentifierPropertyName));
  82:     }
  83:     else
  84:     {
  85:         return (null);
  86:     }
  87: }
  88:  
  89: public static IEnumerable<String> GetIdentifierColumnNames(this ISessionFactory sessionFactory, Type entityType)
  90: {
  91:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
  92:     AbstractEntityPersister persister = (sessionFactory as ISessionFactoryImplementor).TryGetEntityPersister(entityName) as AbstractEntityPersister;
  93:  
  94:     if (persister != null)
  95:     {
  96:         return (persister.IdentifierColumnNames);
  97:     }
  98:     else
  99:     {
 100:         return (null);
 101:     }
 102: }
 103:  
 104: public static String GetColumnName(this ISessionFactory sessionFactory, Type entityType, String propertyName)
 105: {
 106:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
 107:     AbstractEntityPersister persister = (sessionFactory as ISessionFactoryImplementor).TryGetEntityPersister(entityName) as AbstractEntityPersister;
 108:  
 109:     if (persister != null)
 110:     {
 111:         return (persister.GetPropertyColumnNames(propertyName).SingleOrDefault());
 112:     }
 113:     else
 114:     {
 115:         return (null);
 116:     }
 117: }
 118:  
 119: public static String GetTableName(this ISessionFactory sessionFactory, Type entityType)
 120: {
 121:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
 122:     AbstractEntityPersister persister = (sessionFactory as ISessionFactoryImplementor).TryGetEntityPersister(entityName) as AbstractEntityPersister;
 123:  
 124:     if (persister != null)
 125:     {
 126:         return (persister.TableName);
 127:     }
 128:     else
 129:     {
 130:         return (null);
 131:     }
 132: }
 133:  
 134: public static IEnumerable<PropertyInfo> GetCollections(this ISessionFactory sessionFactory, Type entityType)
 135: {
 136:     String entityName = (sessionFactory as ISessionFactoryImplementor).TryGetGuessEntityName(entityType);
 137:     IClassMetadata metadata = sessionFactory.GetClassMetadata(entityName);
 138:     String prefix = String.Concat(entityName, ".");
 139:     IDictionary<String, ICollectionMetadata> collectionMetadata = sessionFactory.GetAllCollectionMetadata().Where(x => x.Key.StartsWith(prefix)).ToDictionary(x => x.Key, x => x.Value);
 140:  
 141:     foreach (String key in collectionMetadata.Keys)
 142:     {
 143:         String propertyName = key.Replace(prefix, String.Empty);
 144:         yield return(entityType.GetProperty(propertyName));
 145:     }
 146: }

A brief explanation:

  • GetProperties: all the mapped properties for a given entity;
  • GetComponents: given an entity type, returns all the properties that are mapped as components;
  • GetUserTypes: all the properties that are mapped as custom user types;
  • GetIdentifier: the property that is mapped as the identifier;
  • GetAssociations: properties mapped as one to one or many to one, that is, that point to another entity;
  • GetCollections: properties mapped as one to many, that is, collections, of any type;
  • GetTableName: the table or view name where the entity is stored;
  • GetIdentifierColumnNames: the names of the column(s) that compose the primary key for the table;
  • GetColumnName: the table or view column that store a given property.

                             

3 Comments

Comments have been disabled for this content.