如何在不使用原始 SQL 字符串的情况下使用 Kentico Pages API 嵌套 WHERE 子句条件?

How to nest WHERE clause conditions using the Kentico Pages API without using raw SQL strings?

我想使用 Kentico Pages API 重新创建此 SQL Where 子句并保持括号完整以改变操作顺序:

WHERE ((EventEnd IS NULL OR EventEnd = '') AND EventStart < getdate()) 
     OR EventEnd < getdate()

注意:不要重新安排此示例以在没有括号的情况下正常工作,因为我的问题是关于使用页面 API.[=18= 生成带括号的复杂条件]

此示例基于理论上的日历事件页面类型,该类型具有:

此 WHERE 子句的目的是通过查找过去的开始日期(如果不存在结束日期值)来过滤过去的事件;否则它会查找过去的结束日期值。

但是我找不到很好的 Kentico 示例来说明如何在不将原始 SQL 字符串放入页面查询中的情况下实现这种条件嵌套(这是可以做到的)。

相反,我正在寻找一种巧妙的方法来使用 .Where(..).And(..).Or(..) 和其他相关的 API 方法来生成上述 WHERE 子句更改后的操作顺序完好无损。 WhereBuilder class 看起来也很有前途,但似乎不符合页面查询的流程。

这是一个 Pages 查询的示例,我试图在其中重新创建上述 WHERE 子句,但不删除条件的原始 SQL 字符串:

using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.Helpers;
using CMS.Base;

var pages = new TreeProvider().SelectNodes()
    .Published()
    .OnSite(MySiteName)
    .Types(CalendarEventPageType)
    .NestingLevel(1)
    .Path(calendarEventsPath, PathTypeEnum.Children)

 /* Looking for clever code after this line...
    How do I group these methods to get the desired order of operations with parenthesis?
   */

    .Where(..) 
    .And(..) 
    .Or(..);

您应该可以像这样添加嵌套 WhereCondition

.Where(new WhereCondition()
        .WhereNull("EventEnd")
        .Or()
        .WhereEmpty("EventEnd")
        .And()
        .WhereLessThan("EventStart", DateTime.Now)
    )
.Or()
.WhereLessThan("EventEnd", DateTime.Now);

参考 Kentico 文档 https://docs.kentico.com/k11/custom-development/retrieving-database-data-using-objectquery-api#RetrievingdatabasedatausingObjectQueryAPI-Nestedwhereconditions

Brenden 的回答让我看到了关于嵌套 WHERE 条件的 Kentico 文档。

以下答案是我通过 API 使用嵌套的 WHERE 条件来完全匹配问题中陈述的 WHERE 子句要求的答案:

DateTime rightNow = DateTime.Now;

var pagesQuery = tree.SelectNodes()
    .OnSite(Mysite)
    .Types(CalEventPageType)
    .Path("/Events/Calendar", PathTypeEnum.Children)
    .NestingLevel(1)

    /* My WHERE Conditions: */
    .Where(w1 => w1.Where(w => w.WhereEmpty("EventEnd").And().WhereLessThan("EventStart", rightNow))
        .Or().WhereLessThan("EventEnd", rightNow))

    .OrderBy(OrderDirection.Descending, "EventStart")
    .Culture("en-ca");

外部 w1 看起来很无聊,但需要在我生成的所有条件周围添加一组外括号,这样它们就不会与 Kentico 的过程冲突。您可以使用条件来查看各种结果。请参阅下面的完整输出。

调用pagesQuery.ToString(true)得到的生成的SQLWHERE子句输出是这样的。它包括我的所有条件(在输出的第二行)和 Kentico 的条件(所有其他行):

WHERE [NodeSiteID] = 1 AND

/* My WHERE Conditions: */
((([EventEnd] = N'' OR [EventEnd] IS NULL) AND [EventStart] < '10/16/2018 10:02:13 PM') OR [EventEnd] < '10/16/2018 10:02:13 PM') 

AND (([DocumentCanBePublished] = 1 
AND ([DocumentPublishFrom] IS NULL OR [DocumentPublishFrom] <= '10/16/2018 10:02:13 PM') 
AND ([DocumentPublishTo] IS NULL OR [DocumentPublishTo] >= '10/16/2018 10:02:13 PM')) 
AND [NodeAliasPath] LIKE N'/Events/Calendar/%' 
AND [NodeLevel] <= 3 AND [DocumentCulture] = N'en-ca')