Dynamic queries using NHibernate with the help of C# expression trees

Jussi Haapanen
Feb 4, 2017 · 4 min read
// NHibernate entities are stored in a single assembly 
// Get all classes from the assembly that MyClass is in
var entities = Assembly.GetAssembly(typeof(MyClass))
.GetTypes()
.Where(x => x.IsClass)
.ToList();
// Input from user
var objectTypeName = "MyClass";
// See if the type actually exists
var objectType = entities
.SingleOrDefault(x => x.FullName.Split('.').Last() == objectTypeName);
// Check if object type was actually found
if (objectType == null) {
// Input isn't valid
throw ...
}
// We need to fetch as "object" as we do not know the type
// compile time.
// We'll pass the object type name as a parameter to tell NHibernate
// what the type actually is.
// NHibernate session should be opened before
var objects = session.Query<object>(objectType.FullName);
// An object taken from the result set from a session.Query call
var someObject = objects.FirstOrDefault();
// Read the value of someObject.SomeProperty
var value = objectType
.GetProperty("SomeProperty")
.GetValue(someObject, null);
Console.WriteLine(value);
var item = Expression.Parameter(typeof(object), "item");// Where(item => item.SomeProperty)
var property = Expression.Property(item, "SomeProperty");
// Where(item => item.SomeProperty.Contains)
var containsMethod = typeof(string)
.GetMethod("Contains", new[]{typeof(string));
// What we're searching for (e.g. SomeProperty.Contains("foo"))
var searchExpression = Expression.Constant("foo", typeof(string));
// Call the "Contains" method for the "SomeProperty" with
// searchExpression as the constant to compare with
var methodExpression = Expression
.Call(property, containsMethod, searchExpression);
// Create a lambda to use inside the where call
var lambda = Expression.Lambda<Func<object, bool>>(methodExpression, item);
// Do the query with the expression
var objects = session
.Query<object>(objectType.FullName).Where(lambda);
// Where(item => item.SomeProperty)
var property = Expression
.Property(Expression.Convert(item, objectType),
"SomeProperty");
// Declare the parameter we're accessing
var item = Expression.Parameter(typeof(object), "item");
// Where(item => item)
var property = Expression
.Property(
Expression.Convert(item, objectType),
"SomeProperty"
);
// Where(item => item.Contains)
var containsMethod = typeof(string)
.GetMethod("Contains", new[] {typeof(string)});
// Where(item => item.Contains("foo"))
var searchExpression = Expression.Constant("foo", typeof(string));
// Call the "Contains" method for the "SomeProperty"
var methodExpression = Expression
.Call(property, method, searchExpression);
// Wrap the method into a lambda
var lambda = Expression
.Lambda<Func<object, bool>>(methodExpression, item);
// Do the NHibernate search with the lambda
var result = session.Query<object>(objectType.FullName)
.Where(lambda);

Jussi Haapanen

Written by

Software Designer at Wapice Ltd

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade