2012-06-19 123 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