Querying Complexity

time to read 1 min | 169 words

When it comes to building search screens, there really isn't something that I would rather use over NHibernate. I am just astounded at how I can slice a very complex scenario into very narrow & clear fashion:

criteria.Add(Expression.Disjunction()
		.Add(Expression.Disjunction()
					.Add(Expression.Eq("City1.id", value))
					.Add(Expression.Eq("City2.id", value))
					.Add(Expression.Eq("City3.id", value))
					.Add(Expression.Eq("City4.id", value))
				)
		.Add(Expression.Conjunction()
					.Add(Expression.IsNull("City1.id"))
					.Add(Expression.IsNull("City2.id"))
					.Add(Expression.IsNull("City3.id"))
					.Add(Expression.IsNull("City4.id"))
			)
	);
cloned.Add(Expression.Disjunction()
			.Add(Expression.In("PreferredArea1", ToArray(Areas)))
			.Add(Expression.IsNull("PreferredArea1"))
	);
cloned.Add(Expression.Disjunction()
			.Add(Expression.In("PreferredArea2", ToArray(Areas)))
			.Add(Expression.IsNull("PreferredArea2"))
	);

Now imagine roughly 20 such cases, all of them can be added/removed dynamically... I am going to write a far longer post about the specification pattern and how it useful it is.

Update: Andrew reminded me that there are easier ways to do this, using operator overloading, let us take the first example and see how it goes:

criteria.Add(
	(
		Expression.Eq("City1.id", value) ||
		Expression.Eq("City2.id", value) ||
		Expression.Eq("City3.id", value) ||
		Expression.Eq("City4.id", value) ||
	) || (
		Expression.IsNull("City1.id") &&
		Expression.IsNull("City2.id") &&
		Expression.IsNull("City3.id") &&
		Expression.IsNull("City4.id") &&
	)
);