A result transformer, in NHibernate, is some class that implements the IResultTransformer interface:
Most query APIs, except LINQ, support specifying a result transformer. So, what is a result transformer used for? Just what the name says: it turns the values obtained from a query into some object. Normally, we just let NHibernate transform these values into instances of our entities, but we may want to do something different, either because we haven’t mapped some class that we want to use, or because we are not returning all of the entity’s properties, etc.
NHibernate includes some result transformers:
- AliasToBeanResultTransformer: allows to transform a result to a user specified class which will be populated via setter methods or fields matching the alias names;
- AliasToBeanConstructorResultTransformer: identical to AliasToBeanResultTransformer, but we specify a constructor for creating new instances of the target class;
- AliasToEntityMapResultTransformer: returns a dictionary where the keys are the aliases and the values the corresponding columns;
- AliasedTupleSubsetResultTransformer: ignores a tuple element if its corresponding alias is null;
- CacheableResultTransformer: used to transform tuples to a value(s) that can be cached;
- DistinctRootEntityResultTransformer: for joined queries, returns distinct root entities only;
- PassThroughResultTransformer: just returns the row as it was obtained from the database;
- RootEntityResultTransformer; returns the root entity of a joined query;
All of these can be obtained from static properties in class NHibernate.Transform.Transformers. NHibernate implicitly uses some of these, for example, LINQ queries always use DistinctRootEntityResultTransformer.
It is easy to build our own transformer. Have a look at the following example:
The TransformTuple method is the one used to turn each returned record into an instance of something. TransformList is called at the end, when all the records have been processed.
The ExpressionResultTransformer class allows us to select which indexes, in the database record, map to which properties in some entity. For our convenience, it offers a number of options to construct an instance (type, constructor + parameters and delegate). We would use it like this: