Как обойти ошибочную доктрину ORM подкачки - PullRequest
0 голосов
/ 09 мая 2018

Я использую Symfony 2.8.39 и Doctrine 2.4.8 и у меня проблемы с постраничными результатами. В основе лежит сервер Mysql5.7.

Документация по подкачке доктрины гласит:

Запросы на разбиение на страницы доктрины не так просты, как вы могли бы подумать в начало. Если у вас есть сложные сценарии выборки-соединения с одним ко многим или ассоциации «многие ко многим», использующие «LIMIT» по умолчанию поставщиков баз данных недостаточно для получения правильных результатов.

https://www.doctrine -project.org / проекты / Доктрина-ОРМ / ен / последний / учебники / pagination.html

Это именно та ситуация, которая у меня есть. Мое утверждение в переводе SQL выглядит так:

SELECT sc.id, sc.name, scc.prio, sd.description
FROM sang_contents sc
JOIN sang_categories_contents scc
JOIN sang_descriptions sd
JOIN sang_languages sl
WHERE
    sc.id = scc.content_id AND 
    scc.category_id = 20 AND
    scc.is_enabled = 1 AND
    sc.id = sd.content_id AND
    sd.language_id = sl.id AND
    sd.description != "" AND
    sl.name = "DE"
ORDER BY scc.prio ASC, sc.id DESC

Поскольку ORM версии 3.0, и эта проблема существует с самого начала, я не думаю, что она будет исправлена ​​в любое время ORM. Так что же делать, чтобы добиться правильных результатов для подкачки?

Моя идея решить эту проблему заключается в том, чтобы разбить на страницы упрощенные данные, которые должны быть в состоянии правильно обрабатывать подкачки:

  • создать таблицу, содержащую результат для всех категорий и языков, и получить к ней доступ с помощью дополнительной сущности. Недостатком является то, что мне придется обновлять эту таблицу каждый раз, когда вносятся изменения в связанные таблицы.

Не могли бы вы предложить другое решение этой проблемы?

Полагаю, стороннее ПО вроде https://github.com/KnpLabs/KnpPaginatorBundle/releases или же https://github.com/whiteoctober/WhiteOctoberPagerfantaBundle/releases просто сидят на вершине пагинации ORM и не решат основную проблему.

Правильно?

Это мой код на данный момент:

    $page = max(0, $request->query->getInt('page', 0));
    $pageRequest = new PageRequest($itemsPerPage, $page);

    $query = $this->em->createQuery(
        'SELECT sc, sd
          FROM NamiApiCoreBundle:Content sc
          JOIN sc.categoryContents scc
          JOIN sc.descriptions sd
          JOIN sd.language sl
            WHERE
            sc.id = scc.content AND
            scc.category = :id AND
            scc.enabled = 1 AND
            sc.id = sd.content AND
            sd.language = sl.id AND
            sd.description != \'\' AND
            sl.iso = :lang
            ORDER BY scc.priority ASC, sc.id DESC'
    )
        ->setFirstResult($pageRequest->getOffset())
        ->setParameter('lang', $lang)
        ->setParameter('id', $categoryId)
        ->useResultCache(true, $this->cache_lifetime);


    if ($itemsPerPage > 0) {
        $query->setMaxResults($pageRequest->getSize());
    }

    $paginator = new Paginator($query);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...