在NHibernate中使用来自两个表和函数的列的谓词的标准

时间:2013-08-01 19:07:01

标签: tsql nhibernate

我的目标是从连接在一起的两个表中获取两个值并执行比较,如果为true,则输出表1中的行。下面的TSQL代码说明了查询,问题是是否有办法执行第三个谓词在使用session.CreateCriteria的NHibernate标准的where子句中:

declare @currentSystemTime datetimeoffset = '2015-07-22 18:42:16.1172838 +00:00'
select 
    inst.ExpiryDate, 
    ent.DaysToExpiryNotificationStart, 
    convert(date, dateadd(day, -ent.DaysToExpiryNotificationStart, inst.ExpiryDate)) as NotificationStart, 
    convert(date, @currentSystemTime) as CurrentSystemTime, 
    * 
from 
    Instances inst
    inner join Entries ent on inst.Entry_id = ent.Id
where
    inst.ExpiryDate is not null
    and ent.DaysToExpiryNotificationStart is not null
    and convert(date, @currentSystemTime) >= convert(date, dateadd(day, -ent.DaysToExpiryNotificationStart, inst.ExpiryDate))

属性在实体类中定义如下:

public virtual DateTimeOffset? ExpiryDate { get; set; }
public virtual int? DaysToExpiryNotificationStart { get; set; }

我正在使用Fluent NHibernate来映射这些。通过CreateQuery或CreateSQLQuery手动查询是唯一的方法吗?如果有更简单的方法来完成这项任务,我就是开放的。任何帮助将不胜感激。

谢谢, 肖恩

1 个答案:

答案 0 :(得分:1)

session.Query<Instances>()
    .Where(i => Datetime.Today >= i.ExpiryDate.AddDays(i.DaysToExpiryNotificationStart))

adddays尚未得到本机支持,但可以很容易地添加。 see here to make AddDays work

使用QueryOver

可以略微不同
session.QueryOver<Instances>()
    .Where(i => Datetime.Today >= i.ExpiryDate.AddDays(i.DaysToExpiryNotificationStart))

public static class QueryOverExtensions
{
    public static void Register()
    {
        ExpressionProcessor.RegisterCustomProjection(() => default(DatTime).AddDays(1), QueryOverExtensions.ProcessAddDays);
    }

    private static IProjection ProcessAddDays(MethodCallExpression methodCallExpression)
    {
        IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection();
        return (Projections.SqlFunction("addDays", NHibernateUtil.DateTime, NHibernateUtil.Int32, property));
    }
}

注意:我不确定adddays是否已定义为sql函数。您可能需要在驱动程序中注册一个