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場合、should/mustはを返しますbool。したがって、この方法で式を再定義できます(SQL Serever構文)

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

括弧は必要ありませんが...)戻り値はboolを表す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の外部でも機能するという利点があります。「Generated」をalwaysに設定して、計算列への書き込みを試みてはならないことをNHibernateマップに通知する必要があります。

于 2012-12-19T17:28:48.013 に答える
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 に答える