2016-09-26 78 views
1

來計算誕生的時代給定日期可以說我有一個類,如下所示:如何使用NHibernate QueryOver

public class Person 
{ 
    public int PersonId {get; set;} 
    public string Firstame {get; set;} 
    public string Lastname {get; set;} 
    public datetime Birthdate {get; set;} 
} 

然後TSQL爲:

select (Firstname + ' ' + Lastname) as Name, 
    Birthdate, 
    case 
     when (month(cast(Birthdate as date)) > month(getdate()) 
     or (day(cast(Birthdate as date)) > day(getdate()) and month(cast(Birthdate as date)) = month(getdate()))) 
      then datediff(year, cast(Birthdate as date), getdate())-1 
     else datediff(year,cast(Birthdate as date), getdate()) 
    end as Age 
from Person 
go 

我是新來NHibernate和QueryOver和我一直試圖想出一種將以下內容翻譯成QueryOver的方法。

case 
    when (month(cast(Birthdate as date)) > month(getdate()) 
    or (day(cast(Birthdate as date)) > day(getdate()) and month(cast(Birthdate as date)) = month(getdate()))) 
     then datediff(year, cast(Birthdate as date), getdate())-1 
    else datediff(year,cast(Birthdate as date), getdate()) 
end as Age 

有關如何使用QueryOver或者更好的IProjection擴展來實現這一點的任何建議?

以下是我一直在尋找的一些材料,但作爲初學者,我很難將一些精妙的東西放在一起。

NHibernate QueryOver CASE WHEN calculate on column value

http://www.andrewwhitaker.com/blog/2014/08/15/queryover-series-part-7-using-sql-functions/

回答

1

鬥爭的一點點後,我能煮了類似於我一直在尋找的東西歸檔。 有可能有更好的解決方案,但現在,這按預期工作。

public IQueryOver<Person> GetQuery(ISession session) 
{ 
    Person person = null; 

    DateTime? endDate = DateTime.Today; 

    SomePersonView dto = null; 

    IProjection birthDate = Projections.Conditional(
     Restrictions.IsNull(Projections.Property(() => person.BirthDate)), 
     Projections.Constant(endDate, NHibernateUtil.DateTime), 
     Projections.Property(() => person.BirthDate)); 

    var personQuery = session.QueryOver<Person>(() => person) 
     .Select(
      Projections.Distinct(
       Projections.ProjectionList() 
        .Add(Projections.SqlFunction("concat", 
          NHibernateUtil.String, 
          Projections.Property(() => person.FirstName), 
          Projections.Constant(" "), 
          Projections.Property(() => person.LastName)).WithAlias(() => dto.Name)) 
        .Add(Projections.Property(() => person.BirthDate).WithAlias(() => dto.BirthDate)) 
        .Add(DateProjections.Age("yy", birthDate, endDate).WithAlias(() => dto.Age)))) 
     .TransformUsing(Transformers.AliasToBean<SomePersonView>()); 

    return personQuery; 
} 

這裏是'DateProjections.Age'來自的擴展名。

public static class DateProjections 
{ 
    private const string DateDiffFormat = "datediff({0}, ?1, ?2)"; 

    // Maps datepart to an ISQLFunction 
    private static Dictionary<string, ISQLFunction> DateDiffFunctionCache = new Dictionary<string, ISQLFunction>(); 

    public static IProjection DateDiff(string datepart, IProjection startDate, DateTime? endDate) 
    { 
     ISQLFunction sqlFunction = GetDateDiffFunction(datepart); 

     return Projections.SqlFunction(
      sqlFunction, 
      NHibernateUtil.Int32, 
      startDate, 
      Projections.Constant(endDate)); 
    } 

    //Get exact age of a person as of today 
    public static IProjection Age(string datepart, IProjection startDate, DateTime? endDate) 
    { 
     IProjection myAge = DateDiff("yy", 
      startDate, endDate); 

     IProjection ageMinusOne = Projections.SqlFunction(
      new VarArgsSQLFunction("(", "-", ")"), NHibernateUtil.Int32, myAge, 
      Projections.Constant(1)); 

     IProjection datePartMonthBirthdate = Projections.SqlFunction("month", NHibernateUtil.Int32, 
      startDate); 

     IProjection datePartDayBirthdate = Projections.SqlFunction("day", NHibernateUtil.Int32, 
      startDate); 

     IProjection datePartMonthCurrentDate = Projections.SqlFunction("month", NHibernateUtil.Int32, 
      Projections.Constant(endDate)); 

     IProjection datePartDayCurrentDate = Projections.SqlFunction("day", NHibernateUtil.Int32, 
      Projections.Constant(endDate)); 

     IProjection myRealAge = Projections.Conditional(
           Restrictions.Or(
            Restrictions.GtProperty(datePartMonthBirthdate, datePartMonthCurrentDate), 
            Restrictions.GtProperty(datePartDayBirthdate, datePartDayCurrentDate) 
            && Restrictions.EqProperty(datePartMonthBirthdate, datePartMonthCurrentDate)), 
           ageMinusOne, 
           myAge); 
     return myRealAge; 
    } 

    private static ISQLFunction GetDateDiffFunction(string datepart) 
    { 
     ISQLFunction sqlFunction; 

     if (!DateDiffFunctionCache.TryGetValue(datepart, out sqlFunction)) 
     { 
      string functionTemplate = string.Format(DateDiffFormat, datepart); 
      sqlFunction = new SQLFunctionTemplate(NHibernateUtil.Int32, functionTemplate); 

      DateDiffFunctionCache[datepart] = sqlFunction; 
     } 
     return sqlFunction; 
    } 
} 
+0

很高興你知道了! –