NHibernate запрос для фильтрации на основе разницы столбцов

#c# #asp.net #nhibernate

#c# #asp.net #nhibernate

Вопрос:

Ниже приведен снимок модели назначения:

 public class Appointment
{
    public virtual DateTime? InTime {get; set;}
    public virtual DateTime? OutTime {get; set;}
}
  

Я хочу, чтобы все встречи, продолжительность которых составляла менее 2 минут. Что-то вроде:

 var twoMinutes = new TimeSpan(0, 0, 2, 0);
var query =
            Repository.QueryOver<DomainModel.Models.Appointment>()
                .Where(a => a.OutTime.Value - a.InTime.Value < twoMinutes);
return query.List();
  

Исключение:

переменная ‘a’ типа ‘DomainModel.Модели.Назначение «ссылается из области видимости «, но оно не определено

Когда я пытаюсь сделать это с помощью QueryOver(), я получаю сообщение об ошибке. Как я могу это сделать, используя ICriteria или любой другой способ в NHibernate?

Комментарии:

1. Есть моменты жизни сервера (C #) и БД. Вычисление разницы — это то, что должно (должно) произойти в DB. So… Создайте проекцию, вычисляющую результат в БД … и сравните с параметром, переданным с сервера

2. Итак, что вы говорите — это должно быть сделано в двух запросах — один, чтобы получить разницу между временем выхода и временем, а другой, чтобы передать разницу и сравнить с двумя минутами?

3. @mridula Для меня это звучит совсем не правильно. Вы получите больше помощи, если ответите на вопрос Liath выше.

4. Я отредактировал вопрос, чтобы добавить ошибку, которую я получаю.

Ответ №1:

Решение здесь, как я уже упоминал в комментарии, состоит в том, чтобы переместить это сравнение в БД. И это должно быть сделано (насколько я знаю) с помощью проекции:

 // two minutes
var twoMinutes = 2d;

// the query
var query = Repository.QueryOver<DomainModel.Models.Appointment>();

// the projection using DATEDIFF
var projection = Projections
    .SqlProjection("DATEDIFF(mi, {alias}.InTime ,{alias}.outTime) as difference"
               , new[] {"difference"}
               , new[] {NHibernateUtil.Double});
  

Теперь мы можем использовать его в запросе:

 query.Where(Restrictions.Ge(projection, twoMinutes));
  

Проверьте

DATEDIFF(datepart,startdate, enddate)

Это означает, что для получения положительного числа первый аргумент должен быть старше…

ПРИМЕЧАНИЕ: некоторые вещи правильно преобразуются механизмом обработки запросов в соответствующий SQL, но это не так…