Verfasst von: Michael | 30/12/2010

Extend NHibernate-LINQ for Regex-Matching

The time between Christmas and New Year’s Eve traditionally is a great time to take a look at .NET-Stuff which is (yet) not part of my daily work. This time I wanted to dig a little deeper into the newest NHibernate version 3.0. I was especially interested in its LINQ-Implementation which was rewritten from scratch for the 3.0-GA release.

Today I tried to extend NH-LINQ with Regex-Matching. What first sounds quite demanding is really easy as NH has many extension points, including the LINQ-Provider.

Add RegexMatch-Function to SQL-Server

SQL-Server doesn’t have Regex-Support out-of-the-box, you need to implement it in .NET as a User-Defined-Function (UDF) and then deploy the assembly to SQL-Server. Here is the very basic implementation which is not optimized for performance in any way (there are some ways to precompile regular expressions):

public class UserDefinedFunctions
  [SqlFunction(IsDeterministic = true, IsPrecise = true)]
  public static bool RegexMatch(SqlString input, SqlString pattern)
    return Regex.IsMatch(input.ToString(), pattern.ToString());

To deploy that function the fastest way is to create a “Visual C# SQL CLR Database Project” which contains the deployment step. I won’t describe it here in details, there are a lot of resources on the net for this topic. Just two remarks: 1) the project must target .NET 3.5 and 2) the CLR-Support in SQL-Server must be activated via

sp_configure ‚clr enabled‘, 1

Implement the Extension-Method

I now add an Extension-Method called “RegexMatch” to the string-Class which has the same implementation as the UDF.

static class RegexExtensions
  public static bool RegexMatch(this string s, string pattern)
    return Regex.IsMatch(s, pattern);

Now “Mike”.RegexMatch(“Mi.e”) evaluates to true while “Mike”.RegexMatch(“Mo.e”) returns false.

Write HQL-Generator for RegexMatch-Method

I have a small NHibernate-Project with one mapped class called “MyUser”:

class MyUser
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }

Not very exciting and I think you can guess how the table looks like. Now I want to do this:

.Where(u => u.Name.RegexMatch("Mi.e"))

Certainly this compiles because of the available Extension-Method but when I execute it I get the following error from NHibernate:

Unhandled Exception: System.NotSupportedException: Boolean RegexMatch(System.String, System.String)

NHibernate doesn’t know what to do with the RegexMatch-Call. We have to tell NHibernate how to translate the LINQ-Expression to a HQL-Expression for the actual UDF-Call.

First we must implement a new so-called HqlGenerator:

public class RegexMatchGenerator : BaseHqlGeneratorForMethod
  public RegexMatchGenerator()
    var methodDefinition =
       ReflectionHelper.GetMethodDefinition(() => 
         RegexExtensions.RegexMatch(null, null));

    SupportedMethods = new[] { methodDefinition };

  public override HqlTreeNode BuildHql(
    MethodInfo method,
    Expression targetObject,
    ReadOnlyCollection<Expression> arguments,
    HqlTreeBuilder treeBuilder,
    IHqlExpressionVisitor visitor
    return treeBuilder.Equality(
      treeBuilder.MethodCall("dbo.RegexMatch", new[]

In the constructor our RegexMatch-Method is registered by using this very cool ReflectionHelper-Class (I must add this to my toolbelt).

In the BuildHql-Method now the magic happens. This code basically is the programmatic representation of “dbo.RegexMatch(@p1, @p2) = 1”. The comparison against 1 is necessary as SQL-Server doesn’t seem to handle RegexMatch as a valid boolean function.

Add HQL-Generator to NHibernate-Configuration

OK, the heavy part is implemented, now we need to register the new HQL-Generator somewhere. That’s easy too. All default HQL-Generators are registered in the class DefaultLinqToHqlGeneratorsRegistry. We must only extend this and add our own HQL-Generator to it:

public class MyLinqToHqlGeneratorsRegistry :
  public MyLinqToHqlGeneratorsRegistry()
    this.Merge(new RegexMatchGenerator());

Last but not least we must set our class as the new HQL-Generator-Registry in the NHibernate-Configuration:


Now when I run the code once more

.Where(u => u.Name.RegexMatch("Mi.e"))

I see this SQL-Query executed:

select myuser0_.Id as Id0_, myuser0_.Name as Name0_
from MyUser myuser0_
where dbo.RegexMatch(myuser0_.Name, @p0)=1;@p0 = ‚Mi.e‘

It works !


The masterminds behind NHibernate seem to have invested a lot of effort to make it as extensible as possible. Great work, guys !



  1. […] managed to solve this by adding my own wild card match generator. See for example of how to register the generator. Here’s the generator incase anyone is […]

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

Du kommentierst mit Deinem Abmelden / Ändern )


Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )


Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s


%d Bloggern gefällt das: