How to Speed Up Build Times With NHQG and MSBuild

I love Ayende’s Rhino projects, especially his NHibernate Query Generator (NHQG). Since on most of my active development I am use NHibernate, Castle, and Rhino.Commons trunks, I keep nhqg in a tools directory and I was using a PreBuild command to generate the query builders. This had the negative impact of always rebuilding my domain project, even if a change was only made in another project. So, here is an msbuild snippet to generate my query builders only when my NHibernate mapping files change.

<ItemGroup>
 <NH-Mappings Include="DomainQuery***.hbm.xml" />
</ItemGroup>
<Target Name="BeforeBuild"
 Inputs="@(NH-Mappings)"
 Outputs="@(NH-Mappings -> '%(RelativeDir)Generated%(Filename).cs')">
  <Exec Command="$(SolutionDir)..toolsnhqgNHQG.exe /lang:cs /files:%22$(ProjectDir)DomainQuery*.hbm.xml%22 /out:%22$(ProjectDir)DomainQueryGenerated%22" />
</Target>

The Inputs and Ouputs of the Target is what allows msbuild to conditionally run the task. I use an msbuild transform to convert my mapping file name into the nhqg generated file name. Also, notice the %22 in command. This is the only way I could figure out how to pass quotes to a cmd inside of msbuild.

And the confirmation…

Target BeforeBuild:
  Skipping target "BeforeBuild" because all output files are up-to-date with respect to the input files.
  Input files: DomainQueryPost.hbm.xml;DomainQueryContributor.hbm.xml;DomainQueryTag.hbm.xml;DomainQueryItem.hbm.xml;DomainQueryBlog.hbm.xml;DomainQueryTagStat.hbm.xml
  Output files: DomainQueryGeneratedItem.hbm.cs;DomainQueryGeneratedTagStat.hbm.cs;DomainQueryGeneratedContributor.hbm.cs;DomainQueryGeneratedBlog.hbm.cs;DomainQueryGeneratedPost.hbm.cs;DomainQueryGeneratedTag.hbm.cs

Happy Building ;)

[tag]nhibernate, rhino, nhqg, .net, msbuild[/tag]

Local and UTC Dates in NHibernate

How do you get a UTC datetime hydrated from NHibernate? Dan Morphis addressed this a while ago with an interceptor.

I proposed a patch to NHibernate that adds UtcDateTime and LocalDateTime data types that will specifically get hydrated with the proper DateTimeKind value instead of DateTimeKind.Unspecified.

Usage
<property name="MyDate" type="UtcDateTime"></property>
<property name="LocalDate" type="LocalDateTime"></property>

You download the patch from Jira, and vote for it if you like it.

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;
}

Read more »