2012-06-19 78 views
3

我想查询一个有多行的表,每个表有一个timestamp,每隔10分钟发送一次数据。我想找到任何丢失的数据,这是一开始那里没有一个timestamp等于未来十年分钟间隔,就像这样:NHibernate QueryOver SQLFunction 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] 

我有这到目前为止,但我看不出如何构建查询,让我做b [时间戳] = DATEADD(MI,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只是不会让我做sqlfunction和我的时间戳的比较。

我希望我在正确的轨道上面的代码,但请纠正我,如果我完全把我在解决这一尝试......

亲切的问候

回答

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字段select ...然后NH不必为常量(1)创建多余的参数。 – dotjoe