2011-10-31 66 views
2

是否有可能獲得由nhibernate在您的代碼中創建的sql,而無需實際運行它?在運行之前捕獲NHibernate生成的SQL並修改

我有一個複雜的標準對象,我通過標準API構建。這個標準對象構成了各種選擇語句的基礎。然後,我可以採用這個基礎,並在我的應用程序中添加不同情景下所需的附加標準。

我現在有必要在我的select語句之一中添加having子句,顯然這不是使用條件api的選項。我可以創造我所需要的投影,如果我查看SQL生成的所有我需要添加到現有標準的底部是...

HAVING SUM(J.HoursAssigned) <> sum(JTB.HourQty) 

它非常令人沮喪的是如此接近,但我似乎無法得到一個額外的行標記到生成的SQL的底部。

我在想,如果我可以提取生成的SQL,那麼我就可以在我需要的having子句上進行標記,並且我可以通過Nhibernate SQLQueryCriteria提交整個事件。

我知道它並不理想,但對於我來說,看起來比在HQL或SQL中編寫一個查詢時其餘部分共享一個通用標準庫更好。

這是可能的,這是一個好主意嗎?任何替代品也將受到歡迎。

+0

相關問題(休眠而不是NHibernate的):http://stackoverflow.com/questions/554481/how-to-get-sql-from-hibernate-criteria-api-not-for-logging –

回答

4

在上面評論中提到的帖子中,我找到了下面的代碼片段,它很好用。

public static string GenerateSQL(ICriteria criteria) 
    { 
     NHibernate.Impl.CriteriaImpl criteriaImpl = (NHibernate.Impl.CriteriaImpl)criteria; 
     NHibernate.Engine.ISessionImplementor session = criteriaImpl.Session; 
     NHibernate.Engine.ISessionFactoryImplementor factory = session.Factory; 

     NHibernate.Loader.Criteria.CriteriaQueryTranslator translator = 
      new NHibernate.Loader.Criteria.CriteriaQueryTranslator(
       factory, 
       criteriaImpl, 
       criteriaImpl.EntityOrClassName, 
       NHibernate.Loader.Criteria.CriteriaQueryTranslator.RootSqlAlias); 

     String[] implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName); 

     NHibernate.Loader.Criteria.CriteriaJoinWalker walker = new NHibernate.Loader.Criteria.CriteriaJoinWalker(
      (NHibernate.Persister.Entity.IOuterJoinLoadable)factory.GetEntityPersister(implementors[0]), 
           translator, 
           factory, 
           criteriaImpl, 
           criteriaImpl.EntityOrClassName, 
           session.EnabledFilters); 

     return walker.SqlString.ToString(); 
    } 
+2

的此代碼的問題在於它不會將參數與查詢內聯,只會看到問號。 –