NHibernate To DataSet
Ayende just posted a very simple solution to converting the result of an NHibernate Query / Criteria to a DataSet. Here is something that I have used in the past.
public DataTable CriteriaToDataTable<CriteriaClass>(ICriteria query, String dataTableName, params String[] properties) { DataTable dt = new DataTable(dataTableName); int i; foreach (String prop in properties) dt.Columns.Add(prop.Replace('.', '_'), ReflectionUtil.GetPropertyType(typeof (CriteriaClass), prop)); foreach (Object obj in query.List()) { i = 0; Object[] vals = new Object[properties.Length]; foreach (String prop in properties) { vals[i] = ReflectionUtil.GetPropertyValue(obj, prop); i++; } dt.Rows.Add(vals); } return dt; }
And the cheap reflection utility
public class ReflectionUtil { ReflectionUtil() { } public static bool InstanceOf<T>(Object instance) { return typeof (T).IsInstanceOfType(instance); } #region Assembly Loading /// <summary> /// Checks if the assembly is loaded in the current AppDomain /// </summary> /// <param name="assemblyName">The full assembly name to search for.</param> /// <returns>true if the assembly is loaded otherwise false</returns> public static bool AssemblyLoaded(String assemblyName) { foreach (Assembly ass in AppDomain.CurrentDomain.GetAssemblies()) { if (ass.GetName().Name.Equals(assemblyName)) return true; } return false; } /// <summary> /// Loads the assembly into the current AppDomain /// </summary> /// <param name="assemblyName">The full assembly name to load into the current AppDomain</param> /// <returns>The loaded assembly</returns> public static Assembly LoadAssembly(String assemblyName) { return Assembly.Load(assemblyName); } #endregion #region Activate Classes /// <summary> /// Attempts to create an instance by calling the default constructor of the class. /// </summary> /// <param name="className">The full class name of the class to activate.</param> /// <param name="assemblyName">The full assembly name containing the class to activate.</param> /// <returns>The activated class</returns> /// <remarks>The class name must be the full name eg. MyNamespace.ClassName</remarks> public static Object CreateLocalInstance(String className, String assemblyName) { Object obj = null; try { Assembly ass = LoadAssembly(assemblyName); obj = Activator.CreateInstance(ass.GetType(className, true, true)); } catch { } return obj; } /// <summary> /// Attempts to create an instance by calling the default constructor of the class. /// </summary> /// <typeparam name="T">The Type to return.</typeparam> /// <param name="className">The full class name of the class to activate.</param> /// <param name="assemblyName">The full assembly name containing the class to activate.</param> /// <returns>The activate class casted to type T</returns> /// <remarks>The class name must be the full name eg. MyNamespace.ClassName</remarks> public static T CreateLocalInstance<T>(String className, String assemblyName) { return (T) CreateLocalInstance(className, assemblyName); } public static T CreateLocalInstance<T>(Type type) { return (T) Activator.CreateInstance(type); } /// <summary> /// Attempts to create an instance by calling the default constructor of the class. /// </summary> /// <typeparam name="T">The Type to return.</typeparam> /// <param name="className">The class to activate.</param> /// <returns>The activate class casted to type T</returns> /// <remarks>The class name must be the full name eg. MyNamespace.ClassName</remarks> public static T CreateLocalInstance<T>(String className) { return (T) Activator.CreateInstance(Type.GetType(className)); } #endregion #region Type Getters /// <summary> /// Returns the Type represented by the assemblyName and className /// </summary> /// <param name="assemblyName">The full assembly name to check for the Type</param> /// <param name="className">The full class name of the Type to get.</param> /// <returns>The Type if found otherwise null.</returns> /// <remarks>The class name must be the full name eg. MyNamespace.ClassName</remarks> public static Type GetType(String assemblyName, String className) { Type t = null; try { t = Type.GetType(className, true, true); } catch { try { Assembly ass = LoadAssembly(assemblyName); t = ass.GetType(className, true, true); } catch { t = null; } } return t; } #endregion public static Object GetPropertyValue(Object rootInstance, String propertyPath) { if (rootInstance == null) return null; Type t = rootInstance.GetType(); if (String.IsNullOrEmpty(propertyPath)) return null; int dotIdx = propertyPath.IndexOf('.'); if (dotIdx <= 0) { return SafeGetProperty(t, propertyPath).GetValue(rootInstance, null); } String prop = propertyPath.Substring(0, dotIdx); return GetPropertyValue(SafeGetProperty(t, prop).GetValue(rootInstance, null), propertyPath.Substring(dotIdx + 1)); } private static PropertyInfo SafeGetProperty(Type t, string property) { try { return t.GetProperty(property); } catch (AmbiguousMatchException) { return t.GetProperty(property, BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance); } return null; } public static T GetPropertyValue<T>(Object rootInstance, String propertyPath) { if (rootInstance == null) return default(T); Type t = rootInstance.GetType(); if (String.IsNullOrEmpty(propertyPath)) return default(T); int dotIdx = propertyPath.IndexOf('.'); if (dotIdx <= 0) return (T) SafeGetProperty(t, propertyPath).GetValue(rootInstance, null); String prop = propertyPath.Substring(0, dotIdx); return GetPropertyValue<T>(SafeGetProperty(t, prop).GetValue(rootInstance, null), propertyPath.Substring(dotIdx + 1)); } public static Type GetPropertyType(Type rootType, String propertyPath) { PropertyInfo pi; if (rootType == null) throw new ArgumentNullException("rootType", "root type is null for property path " + propertyPath); if (String.IsNullOrEmpty(propertyPath)) throw new ArgumentException("propertyPath", "propertyPath cannot be null or empty for type " + rootType.FullName); int dotIdx = propertyPath.IndexOf('.'); if (dotIdx <= 0) { pi = rootType.GetProperty(propertyPath); if (pi != null) return pi.PropertyType; foreach (Type t in rootType.GetInterfaces()) { pi = SafeGetProperty(t, propertyPath); if (pi != null) return pi.PropertyType; } return typeof (Object); } String prop = propertyPath.Substring(0, dotIdx); pi = SafeGetProperty(rootType, prop); if (pi != null) return GetPropertyType(pi.PropertyType, propertyPath.Substring(dotIdx + 1)); foreach (Type t in rootType.GetInterfaces()) { pi = SafeGetProperty(t, prop); if (pi != null) break; } if (pi == null) return typeof (Object); return GetPropertyType(pi.PropertyType, propertyPath.Substring(dotIdx + 1)); } }