Фильтрация Nhibernate по выводу пользовательских функций

Я достаточно новичок в NHibernate, и пока все идет хорошо, но я столкнулся с проблемой, я не совсем уверен, как решить эту проблему. В основном мне нужно фильтровать по выводу пользовательской функции. Если бы я писал на SQL это то, что я написал бы:

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

Я видел атрибут формулы, который я не считаю подходящим, именованные запросы и примеры создания собственного расширения диалекта (которое казалось немного излишним). Я бы подумал, что есть более прямой способ сделать это, но я не могу найти аккуратный пример.

2 ОТВЕТА
РЕШЕНИЕ

Вы можете использовать выражение SQL в ваших запросах гибернации. Предполагая, что вы сопоставили Storeтип, вы можете написать следующий запрос:

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>();
7
10.11.2009 08:44:01

Создание пользовательских расширений диалекта довольно просто:

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

Зарегистрируйте это так:

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

Теперь вы можете использовать ее как любую другую функцию HQL в запросах, подобных тем, которые созданы с помощью session.CreateQuery().

4
10.11.2009 09:06:42
Спасибо за это Асбьёрну. Не то чтобы я думал, что это обязательно тяжело, просто казалось, что это немного убито, учитывая, что это, вероятно, единственное место, где мне нужно было сделать такую ​​вещь. Я буду помнить это для будущих проектов все же. Я все еще учусь, что уместно и когда.
toxaq 10.11.2009 09:19:38
На самом деле, я остановился на этом методе, когда было решено, что нам нужны также значения в выводе. Действительно отличная техника, ура! Единственное, чего не хватало в почти копии и прошлом, было требование «dbo». в начале функции.
toxaq 13.11.2009 06:01:10