Archive

Archive for the ‘NHibernate’ Category

NHibernate Mapping tester

August 29, 2011 2 comments

When using NHibernate, you often need to check if your mappings matches the model and database. Using frameworks like FluentNHibernate usually helps form the compilation perspective, because your mappings won’t compile if there’s any misspelled property or class. But for convensions and database schemas, it’s possible to have a mismatch.
The following code is a test that will check every property on every mapped class and then every collection. Basically, it queries each type and each collection so NHibernate needs to create the sql statement and execute it. If any error is thrown, you will notice.

[Test]
public void AllMappingsAreOk()
{
	var session = GetCurrentNHibernateSession();
	var errors = new List<string>();

	foreach (var entry in session.SessionFactory.GetAllClassMetadata())
	{
		var type = entry.Key;
		var data = entry.Value;

		try
		{
			session.CreateCriteria(type).SetMaxResults(0).List();
		}
		catch (Exception e)
		{
			errors.Add(string.Format("Error getting type {0}: {1}", type, e.Message));
		}

		foreach (var collection in data.PropertyNames.Where(x => data.GetPropertyType(x).IsCollectionType))
		{
			try
			{
				session.CreateCriteria(type).CreateCriteria(collection).SetMaxResults(0).List();
			}
			catch (Exception e)
			{
				errors.Add(string.Format("Error getting collection {0}.{1}: {2}",
										 type,
										 collection,
										 e.Message));
			}
		}
	}
	Assert.True(errors.Count == 0, string.Join(Environment.NewLine, errors));
}

This piece of code was really helpful in the past and is following me in every project involving NHibernate. It seemed useful to share 🙂

Advertisements

Magiq-to-NHibernate: Testing for different mapping strategies

April 24, 2010 2 comments

Magiq has a set of tests for each operation (insert, update, delete and query) that should work for any provider, besides the spescific tests that could be wrote for each provider. The problem I faced when testing nhibernate was how to test several mapping strategies with the same test cases.
The good news is it’s very easy with NUnit 🙂
NUnit fully supports parameterized tests, for test cases and fixtures. Using the Parameterized Test Fixtures feature in NUnit 2.5 I created a mapping folder for each strategy to test and added the folder name as a fest fixture parameter. That’s how the test looks likie:

[TestFixture("subclass")]
[TestFixture("joined-subclass")]
public class MagiqToNHibernateInsertsInheritanceTest {
    //..
}

I love NUnit!

Magiq-to-NHibernate: Collection filtering and moving to NHibernate 3

February 25, 2010 1 comment

Few days ago I started having troubles with Linq-to-NHibernate from the current release 2.1.2. The main problem cames when I design the collection filtering strategy. Basically, my idea was to go from:

parent.ChildCollection

to:

session.Linq<Child>().Single( x=>x.Id == parent.Id ).SelectMany( x=>x.ChildCollection );

Having this, we could add many expressions to that queryable as we want.

The thing is, as Chadly posted, Linq-to-nhibernate 1.0 uses the query parameter (the x in the previous expression) as the criteria alias, so this works:

session.Linq<Child>()
       .Single( x=>x.Id == parent.Id )
       .SelectMany( x=>x.ChildCollection, (p,x) => x )
       .Where( x => x.Something );

but this doen’t:

session.Linq<Child>()
       .Single( x=>x.Id == parent.Id )
       .SelectMany( x=>x.ChildCollection, (p,x) => x )
       .Where( z => z.Something );

Since the chosen strategy for dynamically generating the query involved the definition of the “alias” parameter, and the user will need to know which is, I gave up. So I tried NHibernate 3. And it worked 🙂

It was really painful to change what I’ve done for the old linq provider, because it uses criteria and the new one uses hql. It’s not easy at all to get a IDbCommand from a HQL, but not impossible.

By now, deletes, updates, inserts and bulkinserts are working properly for linq-to-nhibernate 2.0 with the same limitation as before: no inheritance, no collections.
In the next days I will be working on collection support, composite ids and mappings.