2011-09-02 3 views
11

Kiedy wywołuję funkcję setMaxResults w zapytaniu, wydaje się, że chcesz traktować maksymalną liczbę jako "2", bez względu na to, jaka jest rzeczywista wartość.

function findMostRecentByOwnerUser(\Entities\User $user, $limit) 
{ 
    echo "2: $limit<br>"; 
    $query = $this->getEntityManager()->createQuery(' 
     SELECT t 
     FROM Entities\Thread t 
     JOIN t.messages m 
     JOIN t.group g 
     WHERE 
      g.ownerUser = :owner_user 
     ORDER BY m.timestamp DESC 
    '); 
    $query->setParameter("owner_user", $user); 
    $query->setMaxResults(4); 
    echo $query->getSQL()."<br>"; 
    $results = $query->getResult(); 
    echo "3: ".count($results); 
    return $results; 
} 

Kiedy komentuję linię setMaxResults, otrzymuję 6 wyników. Kiedy go zostawiam, otrzymuję 2 najnowsze wyniki. Kiedy uruchomię wygenerowany kod SQL w phpMyAdmin, otrzymuję 4 najnowsze wyniki. Wygenerowany SQL, dla odniesienia, jest:

SELECT <lots of columns, all from t0_> 
FROM Thread t0_ 
INNER JOIN Message m1_ ON t0_.id = m1_.thread_id 
INNER JOIN Groups g2_ ON t0_.group_id = g2_.id 
WHERE g2_.ownerUser_id = ? 
ORDER BY m1_.timestamp DESC 
LIMIT 4 

Edit:

Podczas czytania the DQL "Limit" documentation, natknąłem się na następujący:

Jeśli zapytanie zawiera fetch- dołączył do kolekcji określając metody limitu wyników, które nie działają zgodnie z oczekiwaniami. Ustaw maksymalne wyniki ogranicza liczbę wierszy wyników w bazie danych, jednak w przypadku kolekcjonowania połączonego jedna jednostka główna może pojawić się w wielu wierszach, skutecznie nawadniając mniej niż określona liczba wyników.

Jestem prawie pewien, że nie robię kolekcji połączonej z pobieraniem. Mam wrażenie, że kolekcja połączona z pobieraniem jest tam, gdzie robię coś w stylu: SELECT t, m FROM Threads JOIN t.messages. Czy jestem w błędzie w moim rozumieniu tego?

+0

Właśnie zauważyłem ten sam problem z doktryną 2.2. Jestem zaskoczony, że nie ma obejścia tego problemu ... – Gregoire

Odpowiedz

10

Aktualizacja: Z Nauki 2.2+ można użyć paginator http://docs.doctrine-project.org/en/latest/tutorials/pagination.html

+1

Jakoś nigdy tego nie robię (pamiętaj, robiąc to wcześniej, ale teraz nie mogłem go uruchomić). Pobrane Symfony w zeszłym tygodniu i /var/www/html/Symfony/vendor/doctrine/common/lib/Doctrine/Common/Version.php mówi mi, że jest to wersja 2.3.0. Uruchomienie kodu z linku z wieloma relacjami daje mi licznik ($ paginator) 2143 bez względu na wartość użytych setMaxResults. – HMR

1

Rozwiązałem ten sam problem, pobierając tylko zawartość tabeli głównej i uwzględniając wszystkie połączone tabele jako fetch="EAGER", które jest zdefiniowane w Podmiotie (opisane tutaj http://www.doctrine-project.org/docs/orm/2.1/en/reference/annotations-reference.html?highlight=eager#manytoone).

class VehicleRepository extends EntityRepository 
{ 
    /** 
    * @var integer 
    */ 
    protected $pageSize = 10; 

    public function page($number = 1) 
    { 
     return $this->_em->createQuery('SELECT v FROM Entities\VehicleManagement\Vehicles v') 
      ->setMaxResults(100) 
      ->setFirstResult($number - 1) 
      ->getResult(); 
    } 
} 

W moim przykładzie repo widać, że tylko pobrałem stolik pojazdu, aby uzyskać prawidłową kwotę wyniku. Jednak wszystkie właściwości (takie jak marka, model, kategoria) są pobierane natychmiast.

(. Ja również powtórzyć w ciągu entity-treści, bo potrzebne Podmiot reprezentowany jako tablica, ale to nie powinno mieć znaczenia, AFAIK)

Oto fragment z mojej jednostki:

class Vehicles 
{ 
    ... 

    /** 
    * @ManyToOne(targetEntity="Makes", fetch="EAGER") 
    * @var Makes 
    */ 
    public $make; 

    ... 
} 

Jego ważne jest, aby mapować wszystkie jednostki prawidłowo, w przeciwnym razie nie będzie działać.

5

Korzystanie ->groupBy('your_entity.id') wydają się rozwiązać ten problem!

+0

Po prostu próbowałem tego. Na początku wyglądało na to, że działa, ale wygląda na to, że ogranicza wyniki w pobranych połączonych tabelach. –