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

// 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);

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store