2014-02-27 114 views
1

我的场景:NHibernate用于填充位于网页上的一些网格。数据库是Ms SqlServer 2008/2012,将不会在未来的一年中进行更改。我需要将按DateTime列分组的行(以UTC格式存储为Sql日期时间类型),但仅限日期部分。此外,由于客户可以有不同的时区,我需要按日期以来的offset.The选择是这样的:按当地日期分组

SELECT 
    CAST(CONVERT(char(8), 
     [dbo].fn_LocalDayFromUTCDate(
      this_.datetime1 /* this is CreationTime property mapped by NHibernate to column datetime1 */, 
      -240 /* hour offset and some other TimeZone params */), 
     112 /* timestyle */) AS datetime) as _date 
    FROM SomeTable as this_ 
    GROUP BY CAST(CONVERT(char(8), 
     [dbo].fn_LocalDayFromUTCDate(this_.datetime1, -240),112) AS datetime) 

修订 通过拉迪姆的回答Folowed,我还是设法定制注册自定义SQL的功能方言这样的:

public class CustomMsSql2008Dialect : MsSql2008Dialect 
{ 
    public CustomMsSql2008Dialect() 
    { 
     RegisterFunction(
      "toLocalTime", 
      new SQLFunctionTemplate(
       NHibernateUtil.UtcDateTime, 
       "CAST(CONVERT(char(8), [dbo].fn_LocalDayFromUTCDate(?1, ?2),112) AS datetime)")); 
    }  
} 

public static class CustomProjections 
{ 
    public static IProjection LocalDate(IProjection datePropertyProjection, int offsetInMinutes) 
    { 
     return Projections.SqlFunction(
      "toLocalTime", 
      NHibernateUtil.UtcDateTime, 
      datePropertyProjection, 
      Projections.Constant(offsetInMinutes)); 
    } 
} 

那我已经能够使用这样的:

var groupProjection = Projections.GroupProperty(
    CustomProjections.LocalDate(
     Projections.Property("CreationTime"), 
     -240)); 

问题是,它是生成GROUP BY部分缺失第二参数:

SELECT CAST(CONVERT(char(8), [dbo].fn_LocalDayFromUTCDate(this_.datetime1, @p1),112) AS datetime) as y1_ 
FROM SomeTable this_ 
GROUP BY CAST(CONVERT(char(8), [dbo].fn_LocalDayFromUTCDate(this_.datetime1, ?),112) AS datetime) 
    ORDER BY y1_ asc 

回答

1

上述SELECT和GROUP BY的直接转化成SqlGroupProjection可以是这样的:

var criteria = session.CreateCriteria<SomeEntity>(); // mapped to SomeTable 

criteria.SetProjection(
    Projections.ProjectionList() 
     .Add(
      Projections.SqlGroupProjection(
       " CAST(CONVERT(char(8), " + 
       "  [dbo].fn_LocalDayFromUTCDate( " + 
       "   this_.datetime1 /* this must be mapped by NHibernate column */, " + 
       "   -240 /* hour offset and some other TimeZone params */), " + 
       "  112 /* timestyle */) AS datetime) ", 

       " CAST(CONVERT(char(8), " + 
       " [dbo].fn_LocalDayFromUTCDate(this_.datetime1, -240),112) AS datetime)", 
       new string[] {}, // could be empty, while not used for 
       new IType[] {} // transformation 
       ) 
     )); 

var list = criteria.List<object[]>(); 

还检查:

+0

谢谢你,Radim,我是这样来的,现在已经放在:如何用'Projections.Property(myGroupPropertyAlias)'替换具体列名'this_.datetime1'并让NHbm为我生成它? – dbardakov

+1

我会说,只有认为我们可以在这里做,是用'{别名}'替换* this_ *。这将在后来被NHibernate取代。另一种选择可能是用新的SQL函数扩展方言。它可以稍后与Propety Projection一起使用。一个例子可以在这里找到:http://stackoverflow.com/questions/21725327/。请检查一下,因为在你的情况下,这将是最合适和最好的可维护的 –