Search code examples
c#nhibernatenhibernate-criteriaqueryover

NHibernate COALESCE issue


I am trying to express the following SQL query with NHibernate

DECLARE @date DATETIME = NULL;

SELECT 
    ER.Id
,   ER.DocumentDate
FROM 
    ExpenseReport ER
WHERE
    ER.PeriodFrom >= COALESCE(@date, ER.PeriodFrom)
OR ER.PeriodTo <= COALESCE(@date, ER.PeriodTo);

So, in the C# part I do have the following classes:

  • for the entity : ExpenseReport
  • for my search itself a separate class

Code snippets:

// ----- Entity class.
public partial class ExpenseReport
{
    public Nullable<System.DateTime> PeriodFrom { get; set; }
    // many other properties
}

// ----- Search parameter class.
public class SearchParameters
{
    public Nullable<System.DateTime> DateFrom { get; set; } 
    // many other properties
}

So, assigning now the search parameters to IQueryOver<ExpenseReport>

var q = SessionProvider.QueryOver<ExpenseReport>();

And I am a bit lost now with NHibernate .... How do I do it now?

q.And( /*** I AM STUCK HERE **/)

Solution

  • A drafted code should look like this:

    // left side
    var left = Projections.Property<ExpenseReport>(ti => ti.PeriodFrom);
    // right side
    var right = Projections.SqlFunction("COALESCE"
            , NHibernateUtil.DateTime
            , Projections.Constant(search.DateFrom, NHibernateUtil.DateTime)
            , Projections.Property<ExpenseReport>(ti => ti.PeriodFrom)
        );
    // the restriction using the GeProperty, taking two IProjections
    var restriction = Restrictions.GeProperty(left, right);
    
    // finally - our query get its WHERE
    q.Where(restriction);
    

    So, we firstly create two projections. Then we used the Restrictions utility set to create the >= (GeProperty). Resulting restriction is finally passed into WHERE clause...