2012-06-19 4 views
3

Я хотел бы запросить таблицу с несколькими строками, каждая из которых содержит timestamp с данными, поступающими с интервалом в десять минут. Я хотел бы найти начало любой недостающих данных, что там, где не timestamp сравнявшись следующий десять минутный интервал, например:NHibernate QueryOver SQLFunction in where where

select a.[timestamp] 
from [table] as a 
where not exists (select 1 
        from [table] as b 
        where a.[id] = b.[id] 

        and b.[timestamp] = dateadd(mi, 10, a.[timestamp])) 

order by a.[timestamp] 

меня это до сих пор, но я не вижу, как построить запрос, чтобы позволить мне сделать б [метка] = DateAdd (миль, 10, а [метка].) в приведенном выше запросе:.

Table tableAlias = null; 

IList<DateTimeOffset> dateTimeOffsets = session.QueryOver(() => tableAlias) 
.WithSubquery 
.WhereNotExists(QueryOver.Of<Table>() 
.Where(x => x.Id == tableAlias.Id) 

.And(Restrictions.Eq(Projections.SqlFunction("addminutes", 
              NHibernateUtil.DateTimeOffset, 
              new[] 
              { 
               Projections.Property("Timestamp"), 
               Projections.Constant(10) 
              }), 
              <insert timestamp property again here>)) 

.Select(Projections.Constant(1))) 
.Select(x => x.Timestamp) 
.List<DateTimeOffset>(); 

Я не могу получить мою голову вокруг ограничения на часть sqlfuntion - Nhibernate просто не позволит мне выполнить сравнение функции sql и моей метки времени.

Я надеюсь, что я нахожусь на правильном пути с вышеприведенным кодом, но, пожалуйста, поправьте меня, если я полностью выключен с моей попытки решить эту ...

Сердечные приветы

ответ

2

Вы находитесь на правильном пути. Вам нужно использовать Restrictions.EqProperty вместо Restrictions.Eq, так как вы сравниваете две проекции, а не проекцию и постоянное значение.

Кроме того, вы можете использовать Expression для доступа к свойству TimeStamp внутреннего запроса вместо использования строки.

Следующий код работает для меня на Sql Server 2008, но это может потребовать немного настройки для других СУБД:

Table a = null; 

session.QueryOver<Table>(() => a) 
    .WithSubquery 
    .WhereNotExists(
     QueryOver.Of<Table>() 
      .Where(t => t.Id == a.Id) 
      .And(Restrictions.EqProperty(
       Projections.SqlFunction(
        "addminutes", 
        NHibernateUtil.DateTimeOffset, 
        Projections.Constant(10), 
        Projections.Property(() => a.TimeStamp)), 
       Projections.Property(() => a.TimeStamp))) 
      .Select(Projections.Constant(1))) 
.Select(t => t.TimeStamp) 
.List<DateTimeOffset>(); 

Какой должна генерировать следующий SQL (по крайней мере, на Sql Server 2008):

SELECT this_.TimeStamp as y0_ 
FROM [Table] this_ 
WHERE not exists (SELECT 1 /* @p0 */ as y0_ 
        FROM [Table] this_0_ 
        WHERE this_0_.Id = this_.Id 
          and dateadd(minute, 10 /* @p1 */, this_.TimeStamp) = this_.TimeStamp) 
+0

+1 Обычно я использую поле id для выбора предложения exists ... тогда NH не должен создавать избыточный параметр для константы (1). – dotjoe