我有一个类
public class Account {
public DateTime? StartDate {get;set;}
public DateTime? EndDate {get;set;}
public bool IsActive {get;set;}
}
ISActive属性定义为公式为
.Formula(" StartDate < GETDATE() and (EndDate is NULL or EndDate > GetDate())")
但是,当使用查询查询所有帐户时,iSActive == true时,我会遇到一个错误,即Nhibernate无法执行SQL。
Nhibernate生成的SQL具有
...other criterias...
and this_.StartDate < GETDATE()
and (this_.EndDate is NULL
or this_.EndDate > GetDate()) = 1
如何正确定义公式。
是公式的正确方法,可以超越这样做,或者有一种完全不同的方法
更新:
- 是否可以在不更改基础数据库的情况下进行此操作
谢谢
Formula
在这种情况下必须/必须返回bool
。因此,我们可以以这种方式重新定制公式(sql serever语法):
.Formula(@"
(
CASE
WHEN StartDate < GETDATE() and (EndDate is NULL or EndDate > GetDate())
THEN 1
ELSE 0
END
)
";
(不需要括号,但是...)返回的值是1或0代表bool。因此,现在此QueryOver
将起作用:
var query = session.QueryOver<Account>()
.Where(a => a.IsActive == true);
var list = query.List<Account>();
将表本身上的公式定义为计算列。这也具有在Nhibernate之外工作的好处,而无需复制公式逻辑。您将需要通知您的NHIBERNATE地图,它永远不应尝试通过将"生成"始终设置为计算的列写入计算的列。
我认为这会起作用,但我没有使用NHibernate进行测试以确保正确解释该条件。您必须使用此方法使用LINQ查询。您也可以使用扩展方法采用类似的方法。
public class Account
{
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsActive
{
get { return AccountIsActive(this); }
}
public static readonly Func<Account, bool> AccountIsActive = a =>
{
var now = DateTime.Now;
return (a.StartDate.HasValue && a.StartDate < now) && (!a.EndDate.HasValue || a.EndDate > now);
};
}
用法:
var activeAccounts = session.Query<Account>()
.Where(a => Account.AccountIsActive(a))
.ToList();