【问题标题】:Convert SQL to NHibernate HQL将 SQL 转换为 NHibernate HQL
【发布时间】:2011-09-24 21:39:23
【问题描述】:

我应该将闲置的 SQL-Query 转换为 NHibernate HQL (NHibernate 3.2)。但我不知道,我必须如何翻译 FLOOR、DATEDIFF 和 GETDATE。

SELECT Birthday FROM Person
WHERE 1 = (FLOOR(DATEDIFF(dd,Birthday,GETDATE()+10) / 365.25))
      -
      (FLOOR(DATEDIFF(dd,Birthday,GETDATE()-5) / 365.25))

【问题讨论】:

  • 你想做什么?我看不懂那个查询。
  • @Phill - FLOOR 的定义:返回小于或等于指定数值表达式的最大整数。 FLOOR(DATEDIFF(dd,Birthday,GETDATE()+10) / 365.25) 给我 10 天后的年龄 - FLOOR(DATEDIFF(dd,Birthday,GETDATE()-5) / 365.25) 给我 5 天的年龄在过去。如果这个差值为 1,则生日在从现在开始的过去 5 天到未来 10 天之间。

标签: sql nhibernate hql


【解决方案1】:

开始做点什么。

选择从现在-5 天到现在+10 天之间的生日。

罢工>

    var today = DateTime.Now();
    var results = session.CreateQuery("select p.Birthday from Person 
        where p.Birthday>= :from and p.Birthday<=:to")
    .SetParameter("from", today.AddDays(10))
    .SetParameter("to", today.Subtract(new TimeSpan(5, 0, 0, 0)))
    .List<DateTime>();

虽然我觉得你不管什么年份都想过生日。

为了在 HQL 中复制此查询,您必须使用此技术注册所需的特定 SQL 函数:

Register Custom SQL Function in NHibernate

那么您应该能够在 HQL 中复制您的 SQL 查询。

这是一个关于 SQL 方面的好问题:

SQL Select Upcoming Birthdays


新鲜战术:

为 datediff 注册 SQL 函数:

RegisterFunction("datediffdays", 
    new SQLFunctionTemplate(NHibernateUtil.Int32, "datediff(dd,?1, ?2)"));

HQL 查询

var result = session.CreateQuery(@"from Person
     where 1 = (floor(datediffdays(Birthday,current_timestamp()+10) / 365.25))
    - (datediffdays(Birthday,current_timestamp()-5) / 365.25))")
.List<Person>();

【讨论】:

【解决方案2】:

未经测试,但会是这样的: 罢工>

var dateStart = DateTime.Now.AddDays(-5).Ticks/365.25D;
var dateEnd = DateTime.Now.AddDays(10).Ticks/365.25D;

session.QueryOver<Person>()
    .WhereRestrictionOn(x => x.Birthday.Ticks/365.25D)
         .IsBetween(dateStart).And(dateEnd)
    .List();

这做同样的事情吗?


看源码,楼在方言中已经注册了,所以如下:

var result =
    session.CreateQuery(@"from Person 
                          where 1 = (FLOOR(DATEDIFF(dd,Birthday,GETDATE()+10) / 365.25))
                                        -
                                    (FLOOR(DATEDIFF(dd,Birthday,GETDATE()-5) / 365.25))")
           .List<Person>();

产生以下 SQL:

select person0_.Id       as Id2_,
       person0_.Birthday as Birthday2_
from   [Person] person0_
where  1 = floor(DATEDIFF(dd,
                          person0_.Birthday,
                          GETDATE()
                            + 10)
                   / 365.25)
             - floor(DATEDIFF(dd,
                              person0_.Birthday,
                              GETDATE()
                                - 5)
                       / 365.25)

【讨论】:

  • C# 中的刻度从 0001 年 1 月 1 日开始工作,但在 SQL Server 中,它们从不同的日期开始工作,具体取决于列类型,DateTime (SQL 2000) 与 DateTime2 (SQL 2008)。
  • @Mark - 好点,没想到这一点。很明显,现在思考已经太晚了。
  • 这给了我异常消息:无法确定来自 (Convert(x.Birthday.Value.Ticks) / 365,25) 的成员。生日在我这边是 Nullable-DateTime。
  • @t.kehl - 由于 Marks 对 .NET 和 SQL Server 之间的日期时间差异的评论,我删除了该解决方案。
猜你喜欢
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 2014-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多