1

berechnen Lets sagen, dass ich eine Klasse wie folgt:Wie Alter angegeben Geburtsdatum mit 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;} 
} 

Dann TSQL wie:

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 

Ich bin neu in NHibernate und QueryOver und i habe versucht, eine Möglichkeit zu finden, das Folgende in QueryOver zu übersetzen.

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 

Haben Sie Vorschläge, wie dies mit QueryOver oder besser als IProjection-Erweiterung erreicht werden kann?

Das Folgende sind einige der Materialien, die ich mir angeschaut habe, aber da ich ein Anfänger bin, fällt es mir schwer, etwas zusammen zu setzen.

NHibernate QueryOver CASE WHEN calculate on column value

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

Antwort

1

Nach einem wenig Kampf, konnte ich etwas ähnliches wie kochen, was ich zu archivieren suchte. Es gibt vielleicht bessere Lösungen, aber im Moment funktioniert das wie erwartet.

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; 
} 

Und hier ist die Verlängerung, wo 'DateProjections.Age' herkommt.

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

Froh, dass Sie es herausgefunden haben! –

Verwandte Themen