NHibernate with LINQ: Error with String Comparisons in VB.NET

If you’re in VB.NET using LINQ to NHibernate and you get this error on a simple query:

System.ArgumentException : Expression of type ‘System.Int32’ cannot be used for return type ‘System.Boolean’

Then I’ve got an explanation and a fix for you.

Here’s a query that will produce this error:

Dim result = nhQueryProvider.Where(Function(code) code.Name = “OPEN”)

If you load up the NHibernate.Linq code and debug through it, you find that the Expression being evaulated is not what you’d guess.  You’d think it would be something simple:

  • code.Name = “OPEN”

But actually it’s something like this:

  • CompareString(code.Name, “OPEN”) = 0

So that at least gives a clue about where the Int32/Boolean confusion is coming from.  Here is an old explanation of what the VB compiler is doing to for you:


It’s pretty easy to modify the NHibernate.Linq’s ExpressionVisitor with the fix suggested in the post above.

I am using NHibernate.Linq  I see that Linq support is currently in NHibernate Core’s trunk, and that it’s changed quite a bit since the GA, so hopefully the next version will handle VB string comparison in a more predictable way.

Since the fix in the link above is in VB, here’s the C# translation for your convenience:

private static BinaryExpression FixVbStringComparison(BinaryExpression exp)
if (exp.Left.NodeType == ExpressionType.Call)
var compareStringCall = (MethodCallExpression)exp.Left;
if (compareStringCall.Method.DeclaringType.FullName == “Microsoft.VisualBasic.CompilerServices.Operators”
&& compareStringCall.Method.Name == “CompareString”)
var arg1 = compareStringCall.Arguments[0];
var arg2 = compareStringCall.Arguments[1];
switch (exp.NodeType)
case ExpressionType.LessThan: return Expression.LessThan(arg1, arg2);
case ExpressionType.LessThanOrEqual: return Expression.GreaterThan(arg1, arg2);
case ExpressionType.GreaterThan: return Expression.GreaterThan(arg1, arg2);
case ExpressionType.GreaterThanOrEqual: return Expression.GreaterThanOrEqual(arg1, arg2);
default: return Expression.Equal(arg1, arg2);
return exp;


This entry was posted in Uncategorized. Bookmark the permalink.