2014-03-28 235 views
0

我想使用一個SQL函數來過濾查詢結果篩選結果。我在SQL中有一個名爲SplitKeys的函數,它接收一個csv字符串並返回一個整數表。我想生成以下SQL(或接近):使用NHibernate功能與QueryOver

SELECT * FROM成員那裏MemberKey在(SELECT * FROM SplitKeys( '1,2,3'))I''m使用QueryOver

並且似乎無法獲得產生where子句的內容。因爲我無法得到那個工作,我創建了一個字符串和ID和返回的ID,如果它是在列表中,或-1,如果沒有其他功能。

session.QueryOver<Member>().Where(
    Restrictions.Ge(
     Projections.SqlFunction(
      "dbo.IsKeyInList", 
      NHibernateUtil.StringClob, 
      new[] 
      { 
       Projections.Constant(
        keyList, 
        NHibernateUtil.StringClob), 
       Projections.Constant(',', NHibernateUtil.Character), 
       Projections.Property<Member>(x => x.MemberKey) 
      }), 
    0)); 

這很好,除了它很慢。在第一個查詢中,該函數被調用一次,然後可以基於該表進行過濾。在第二個調用每行的函數。

我本來這是整數的列表,並通過了。但是,與這個問題是列表中的每個元素是在SQL參數和最大參數是2100

session.QueryOver ().WhereRestrictionOn(X => x.MemberKey).IsInG(intKeyList);

我看了又看,似乎無法找到誰做了那個或得到NHibernate和C#編譯器的喜歡。我試過這個,它不起作用。這個和其他的變體或者拋出一個異常,沒有爲System.In32映射或者它什麼都不返回。

var keys = 
    session.QueryOver<MemberKey>() 
     .Select(
      Projections.SqlFunction(
       "dbo.SplitKeysCSV", 
       NHibernateUtil.StringClob, 
       new[] { 
        Projections.Constant(keyList), 
        Projections.Constant(delimiter), 
       })); 

我試着爲結果創建某種映射,但我不能那樣做,因爲沒有表。我嘗試使用.In()函數,但不接受一個Projects.SqlFunction。

回答

0

您可以使用SqlCriterion做到這一點:

var sqlCrit = new SQLCriterion("{alias}.MemberKey in (SELECT * FROM dbo.SplitKeys(?))", 
       new[]{ keyList }, new IType[]{ NHibernateUtil.String }) 
var keys = session.QueryOver<Member>() 
      .Where(sqlCrit) 
+0

是的,這確實起作用。幾乎。兩個輕微的變化。它是{別名} .MemberKey,你必須調用SqlString.parse而不是新的SqlString()。 –