Archive

Posts Tagged ‘NHibernate’

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: 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.

Magiq-to-NHibernate: First commit!

February 22, 2010 1 comment

The past weekend I started to play with NHibernate for getting Magiq-to-NHibernate features up. It’s wonderful to work with an actually well done-designed framework 🙂
By now, only updates and deletes are working, and for simple classes that doesn’t have subclasses. Collection operations aren’t done either. Oh, and also it only works with SQL Server.
I know the actual problem will be when adding support to joined and union subclasses… well… one step at a time 🙂

Magiq: Querying a collection

January 11, 2010 1 comment

One of the future features of Magiq will be mass operations to collections. I mean that

var country = CountryRepository.GetById(1);
country.Cities.Where( x => x.Population > 100000 ).Set( x => x.IsBigCity, true ).Update();

should generate a t-sql like

UPDATE [t0] SET [t0].IsBigCity = @p2 FROM Cities [t0] where [t0].Population > @p1 AND [t0].CountryId = @p2

Of course, this should be possible only if the collection is a Lazy one, so all the information needed is inside of it (it’s the same information needed to retrieve the items). For Linq-to-sql is EntitySet. For NHibernate, AbstractPersistentCollection (PersistentGenericBag, PersistentGenericList, PersistentGenericSet and PersistentGenericMap).

The problem (because there’re always problems) is that those classes doesn’t implement IQueryable and the previous magiq statement will work always as magiq-to-objects, because the collection is enumerated once the Where extension method is called and the Set method is called to a simple IEnumerable.

Talking with Sebas and my friend Jonas, we conclude that the best way to solve this is adding an extension method ToQueryable that converts the lazy enumerable to a queryable one (I would like to call it “AsQueryable”, but it already exists :S). I know, it’s a workaroud, but… it seem like I have no choice.

So, the API will look like:

var country = CountryRepository.GetById(1);
country.Cities.ToQueryable().Where( x => x.Population > 100000 ).Set( x => x.IsBigCity, true ).Update();

The great news is that you can use it for sub selecting collections. It would be the same feature that nhibernate has, but for all the orm’s that have lazy collections (of course, nhibernate magiq provider will implement this feature using it own feature).

Something like:

var country = CountryRepository.GetById(1);
country.Cities.ToQueryable().Where( x => x.Population > 100000 );

will execute

SELECT [t0].Id, [t0].Population, [t0].Name FROM Cities [t0] where [t0].Population > @p1 AND [t0].CountryId = @p2

Isn’t it pretty?

There’s not NH vs EF

December 25, 2009 Leave a comment

Today Ayende wrote a post about how EF is better than NH (ok, it is actually about how EF is not better than NH) and I started writing a comment about it when I realized that it was really long and it will fit better in a post. So here it is:

There are two kind of people in .NET world. The ones that likes the language and uses the framework and features following a regular OO development (people that could work in java, ruby, smalltalk, c++, etc) and the ones that does whatever microsoft says, the people that are evangelized. Don’t forget .NET is full of people that worked a lot of time with VB6 and ASP 3.

When .NET cames, it added a pretty good feature, inheritance, and people could start thinking about it. The data access was solved with datasets, that worked a lot like recordset (from the api perspective). But microsoft always suggested to use typed datasets, so developers would use strong typed properties instead of strings. A small step for man, a giant leap for mankind.

Then linq-to-sql came, so you can have objects representing your tables. Each column is “mapped” to a property. Even those foreign keys, but you have also the actual association, so you don’t need to make another select! I think they are educating people and once the developers get used to it, they could remove the fk property from the class. Baby steps, again.

I know, for NH guys all this is trivial, but try to talk about mappings, first level cache, second level cache, inheritance mapping strategies, query cache, multiple databases support, query substitutions, lazy loading, batch size, fetching strategies, custom types, etc. with someone that still thinks from the database schema perspective. Come on, there are people that writes a stored procedure for a simple insert, just because there’s a myth about the stored procedure performance!

There’s not NH vs EF. There’s NH for those that work as community does and EF for the ones that goes to church every sunday morning.

Categories: C# Tags: ,