簡體   English   中英

我可以在不使用where子句的情況下創建自定義表達式嗎?

[英]Can I create a custom expression without using the where clause?

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

這是我正在使用的。 看看生成什么,我可以說它正在生成正確的語句減去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);

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

編輯:現在我認為它看起來像是在咆哮錯誤的樹。 雖然這不是至關重要的(我已經有了不錯的實施)。 我仍然有興趣了解如何進一步定制NHibernate。

編輯2:由於開箱即用NHibernate不支持Oracle的專有功能,所以start with ... connect by 我正在嘗試通過添加對它的本機支持來學習更多關於擴展NHibernate的知識。 我知道我可以用自定義方言注冊這些功能。 但我想知道是否可以將其作為Criteria實現,以便我可以將其與其他標准查詢一起使用。 我發布的代碼工作正常並正確創建有效的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一起使用。 您可以在此處詳細了解這些關鍵字的工作原理。

我不知道現有的NHibernate語法是否允許這樣做,但是有一種ANSI標准語法可用於分層查詢,這可能有用。 我相信它只適用於11R2及以上,所以我不確定它是否對你有用。 有關更多信息,請參閱遞歸子查詢重構

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM