4

我有一堂课

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 的所有帐户时,我收到 NHibernate 无法执行 SQL 的错误。

NHibernate 生成的 SQL 有

...other criterias...
and this_.StartDate < GETDATE()
   and (this_.EndDate is NULL 
         or this_.EndDate > GetDate()) = 1

如何正确定义公式。

公式是超越这样做的正确方法,还是有完全不同的方法来解决它

更新 :

  • 有没有办法在不改变底层数据库的情况下做到这一点

谢谢

4

3 回答 3

3

在这种情况下,Formula应该/必须返回bool. 因此,我们可以通过这种方式重新定义公式(SQL Server 语法)

.Formula(@"
(
  CASE
    WHEN  StartDate < GETDATE() and (EndDate is NULL or EndDate > GetDate())
     THEN 1
     ELSE 0
  END
)
";

括号不是必需的,但是...)返回值为 1 或 0 表示布尔值。所以现在这QueryOver将起作用:

var query = session.QueryOver<Account>()
           .Where(a => a.IsActive == true);
var list = query.List<Account>();
于 2012-12-20T07:01:49.800 回答
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();
于 2012-12-19T18:04:32.487 回答
0

将表本身的公式定义为计算列。这也具有在 NHibernate 之外工作的好处,而无需复制公式逻辑。您需要通知您的 NHibernate 映射,它不应该通过将“生成”设置为始终尝试写入计算列。

于 2012-12-19T17:28:48.013 回答