2012-12-19 117 views
4

我有定義使用功能NHibernate

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 

如何正確定義的公式。

是式正道上面去這樣做還是有一個完全不同的方式去了解它

更新:

  • 有沒有辦法做到這一點不改變標的數據庫

由於

回答

3

Formula應/必須在這種情況下返回bool。因此,我們可以redifine公式這樣(SQL語法Serever)

.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>(); 
+0

我的解決方案達成一致,但對初始聲明:這不是它,而相反的 - 原來的公式返回一個bool這是一個「隱藏」類型的SQL Server假裝不存在,我們需要將其轉換爲整數類型(通常是位)? –

+0

實際上最初的語句返回:'NHibernate不能執行SQL' –

+0

我覺得我不清楚。我的意思是你的陳述「公式應該/必須在這種情況下返回布爾」。但我認爲它已經是bool了,並且您的解決方案(正確)轉換爲整數類型。 (是的,我在這挑選:) :) –

0

定義在TABL式e本身作爲computed column。這有利於在NHibernate之外工作,而不需要複製公式邏輯。您將需要通知您的NHibernate映射,它永遠不應該試圖通過將「生成」設置爲始終寫入計算列。

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();