Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nhibernate filtering by user defined function output

I'm reasonably new to NHibernate and everything has been going pretty well so far but I've come across a problem I'm not exactly sure of how to go about solving. Basically I need to filter by the output of a User Defined function. If I was writing in SQL this is what I'd write:

declare @Latitude decimal
declare @Longitude decimal
declare @radius int

set @Latitude = -118.4104684 
set @Longitude = 34.1030032

select  * 
from    store
where   dbo.CalculateDistance([Latitude], [Longitude], @Latitude, @Longitude) < @radius

I've seen the formula attribute which I don't think is appropriate, named queries and examples of creating your own dialect extension (which seemed a little over kill). I would've thought there was a more straight forward way of doing it but I can't seem to find a tidy example.

like image 634
toxaq Avatar asked Dec 23 '22 08:12

toxaq


2 Answers

You could use SQL expression in your hibernate queries. Assuming you've mapped a Store type you could write the following query:

var result = session
    .CreateCriteria<Store>()
    .Add(Expression.Sql(
        "dbo.CalculateDistance({alias}.Latitude, {alias}.Longitude, ?, ?) < ?",
        new object[] { 
            -118.4104684d, 
            34.1030032d, 
            100 
        },
        new IType[] { 
            NHibernateUtil.Double, 
            NHibernateUtil.Double, 
            NHibernateUtil.Int32 
        }
    ))
    .List<Store>();
like image 190
Darin Dimitrov Avatar answered Jan 08 '23 00:01

Darin Dimitrov


Creating custom dialect extensions is rather easy:

public class CustomFunctionsMsSql2005Dialect : MsSql2005Dialect 
{ 
   public CustomFunctionsMsSql2005Dialect() 
   { 
      RegisterFunction("calculatedistance",
                       new SQLFunctionTemplate(NHibernateUtil.Int32,
                                               "CalculateDistance(?1, ?2, ?3, ?4)"));
   }
}

Register it, like so:

<property name="hibernate.dialect">
  CustomFunctionsMsSql2005Dialect, MyAssembly
</property>

Now you can use it like any other HQL function in queries like those created with session.CreateQuery().

like image 36
Asbjørn Ulsberg Avatar answered Jan 07 '23 23:01

Asbjørn Ulsberg