2010-08-19 48 views
3

雖然我已經在使用本機查詢的上一個問題中解決了此問題。我現在想知道是否可以在不使用where子句的情況下創建可在Criteria中使用的自定義表達式?我不想要where子句的原因是因爲Oracle的connect by ... start with ...here)聲明。我按照this頁面來開始。但是,這將生成類似select * from foo where connect by start with的代碼...我可以在不使用where子句的情況下創建自定義表達式嗎?

這是我正在使用的。看看生成的東西,我可以說它正在生成正確的語句減去where子句。

public class StartWithConnectByCriteria : AbstractCriterion 
{ 
    public StartWithConnectByCriteria(string parentName, string parentValue, string childName) 
    { 
     ParentName = parentName; 
     ParentValue = parentValue; 
     ChildName = childName; 
    } 

    public string ParentName { get; set; } 
    public string ParentValue { get; set; } 
    public string ChildName { get; set; } 
    public IProjection P { get; set; } 

    public override IProjection[] GetProjections() 
    { 
     if(P != null) 
     { 
      return new IProjection[] {P}; 
     } 
     return null; 
    } 

    public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) 
    { 
     return 
      CriterionUtil.GetTypedValues(criteriaQuery, criteria, P, ParentName, ParentValue.ToString()); 
    } 

    public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, 
              IDictionary<string, IFilter> enabledFilters) 
    { 
     var sqlBuilder = new SqlStringBuilder(); 
     SqlString[] parentColumnNames = CriterionUtil.GetColumnNames(ParentName, 
                   P, criteriaQuery, 
                   criteria, enabledFilters); 
     SqlString parentColumnName = parentColumnNames[0]; 

     SqlString[] childColumnNames = CriterionUtil.GetColumnNames(ChildName, 
                P, criteriaQuery, 
                criteria, enabledFilters); 
     SqlString childColumnName = childColumnNames[0]; 

     criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); 
     sqlBuilder 
      .Add("start with " + parentColumnName + " = '" + ParentValue + "'") 
      .Add(" connect by prior " + childColumnName + " = " + parentColumnName); 

     return sqlBuilder.ToSqlString(); 
    } 

    public override string ToString() 
    { 
     return ""; 
    } 
} 

我正在像這樣使用它。

StartWithConnectByCriteria criterion = 
    new StartWithConnectByCriteria(
     "parent", 
     "parent_value", 
     "child"); 

DetachedCriteria dc = DetachedCriteria.For<NormalUpstream>("nu") 
    .Add(criterion); 

我有它與.Add()從的DetachedCriteria,但不是100%肯定做的感覺。不幸的是,我似乎找不到有關創建自定義表達式的文檔。

編輯:現在我想起它看起來像我吠叫錯了樹。雖然這不是關鍵(我已經有一個體面的實施)。我仍然對如何進一步定製NHibernate感興趣。

編輯2:由於開箱即用,NHibernate不支持Oracle的專有功能,start with ... connect by。我試圖通過添加本地支持來了解更多關於擴展NHibernate的信息。我知道我可以使用自定義方言註冊這些功能。但是我想知道是否有可能將它作爲一個標準來實現,所以我可以將其與其他條件查詢一起使用。我發佈的代碼工作正常,並正確地創建有效的SQL,但是當我將StartWithConnectByCriteria添加到我的標準時,NHibernate將發出一個查詢,如select this_.id from table where start with ... connect by。這是一個無效的查詢,因爲該子句不屬於where。

這是我期望NHibernate生成的查詢。

select 
    random_column 
from 
    table 
start with parent_id = 'parent_node_id' 
connect by prior child_up_id = parent_id 

請注意此查詢中沒有where子句。但是,start with ... connect by仍然可以與where clause一起使用。你可以閱讀更多關於這些關鍵字是如何工作的here

回答

0

我不知道現有的NHibernate語法是否允許這樣做,但是對於可能證明有用的分層查詢有ANSI標準語法。我相信它只適用於11R2及以上版本,所以我不確定它是否對您有用。有關更多信息,請參閱Recursive Subquery Refactoring

+0

我不認爲Criteria API支持'WITH'。我可能能夠使用HQL或本機SQL查詢與我們脫身。謝謝。 – Mike 2010-10-25 12:53:02

相關問題