查询不会在Silverstripe 3.4中返回$ belongs_many_many相关对象

时间:2017-05-16 23:43:26

标签: php silverstripe datamodel

我有很多ArticlePage个,可以出现在很多BlogPage上,但ArticlePage::get()->filter('BlogPage.ID', $parentID)不会从数据库中返回预期的ArticlePage

我已检查过网页是否已发布,BlogPage_ArticlePages表是否正确存储了这些关系。

BlogPage.php

class BlogPage extends Page {
    ...

    private static $many_many = array(
        'ArticlePages' => 'ArticlePage'
    );

    ...
}

ArticlePage.php

class ArticlePage extends Page {
    ...
    private static $belongs_many_many = array(
        'BlogPages' => 'BlogPage'
    );
    ...
}

列表/查询

$parentID = 12;
ArticlePage::get()->filter('BlogPages.ID', $parentID);

1 个答案:

答案 0 :(得分:2)

这对我有用

$parentID = 12;
$query = ArticlePage::get()->innerJoin(
    $table = '(SELECT "BlogPage_ArticlePages"."ArticlePageID" FROM "BlogPage_ArticlePages" INNER JOIN "BlogPage" ON "BlogPage_ArticlePages"."BlogPageID" = "BlogPage"."ID" WHERE "BlogPage"."ID" = ?)',
    $onClause = '"BlogPage"."ArticlePageID" = "SiteTree"."ID" ',
    $alias = "BlogPage",
    $order = 20,
    $parameters = array($parentID)
);

BlogPageArticlePage都是SiteTree的后代,因此需要更明确的表达式来避免在生成的查询中出现命名冲突。

Silverstripe开发人员TractorCow告诉我,Silverstripe 3映射查询的方式有一些限制,并给了我解决方法,但建议如果时间允许,可以进一步改进

<强>解释

当Silverstripe 3为SiteTree的后代形成SQL查询时,它使用SiteTree表(和SiteTree“作为别名”)。将->filter('BlogPage.ID')添加到查询后,Silverstripe将SiteTree用作别名(再次)。这造成了引用冲突,并且没有匹配的记录。

上面的->innerJoin()查询相关的BlogPage数据,并将其别名为BlogPage而不是SiteTree$table中的( )表达式是一个“周期性”引用,它提供了一些我们可以更恰当的别名。