我有一个班级
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())")
但是当使用QueryOver查询IsActive == true的所有Account时,我得到一个NHibernate无法执行SQL的错误。
NHibernate生成的SQL
...other criterias...
and this_.StartDate < GETDATE()
and (this_.EndDate is NULL
or this_.EndDate > GetDate()) = 1
如何正确定义公式。
Formula是正确的方法,还是有一种完全不同的方式来实现它
更新:
由于
答案 0 :(得分:3)
在这种情况下,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>();
答案 1 :(得分:0)
将表格本身的公式定义为computed column。这样做的好处是可以在NHibernate之外工作,而无需复制公式逻辑。您需要通知您的NHibernate映射它永远不应该尝试通过将“Generated”设置为计算列来写入计算列。
答案 2 :(得分:0)
我认为这会有效但我没有用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();