Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][Symfony2][Doctrine2] Problem z utworzeniem zapytania w Doctrine
Forum PHP.pl > Forum > PHP > Frameworki
rcetra
Witam,

uczę się Symfony2 od jakichś 3 tygodni. Do tej pory jakoś znajdywałem rozwiązania zagadek, które napotykałem. Tym razem potrzebuję pomocy.
Jest projekt aplikacji do tłumaczenia tekstów. Celem jest wystawienie aplikacji, dzięki której tłumacze będą mogli tłumaczyć teksty z aplikacji lub dokumentacji. Są 4 tabele, które zawierają teksty do tłumaczenia. Definicje bazy danych:
  1. BDK\TranslatorBundle\Entity\TranslatorText:
  2. type: entity
  3. table: translator.tbl_txt_text
  4. fields:
  5. txt_id:
  6. id: true
  7. type: integer
  8. generator:
  9. strategy: AUTO
  10. txt_name:
  11. type: text
  12. notnull: true
  13. unique: true
  14. txt_description:
  15. type: text
  16. notnull: true
  17. oneToMany:
  18. body:
  19. targetEntity: TextBody
  20. mappedBy: txt_id
  21. indexBy: ted_txt_id
  22. manyToOne:
  23. txt_tap_id:
  24. targetEntity: TranslatorApp
  25. inversedBy: text_body
  26. joinColumn:
  27. name: txt_tap_id
  28. referencedColumnName: tap_id
  29. onDelete: CASCADE
  30. lifecycleCallbacks: { }

  1. BDK\TranslatorBundle\Entity\TranslatorLang:
  2. type: entity
  3. table: translator.tbl_lng_language
  4. id:
  5. lng_id:
  6. type: integer
  7. generator:
  8. strategy: AUTO
  9. fields:
  10. lng_name: { type: string, length: 100 }
  11. lng_shortcut: { type: string, length: 10 }
  12. lng_img: { type: text, nullable: true }
  13. oneToMany:
  14. text:
  15. targetEntity: TextBody
  16. mappedBy: lng_id
  17. indexBy: ted_lng_id
  18. lifecycleCallbacks: { }

  1. BDK\TranslatorBundle\Entity\TextBody:
  2. type: entity
  3. table: translator.tbl_ted_text_body
  4. fields:
  5. ted_id:
  6. id: true
  7. type: integer
  8. generator:
  9. strategy: AUTO
  10. ted_description:
  11. type: text
  12. notnull: true
  13. ted_body:
  14. type: text
  15. notnull: true
  16. manyToOne:
  17. ted_txt_id:
  18. targetEntity: TranslatorText
  19. inversedBy: body
  20. joinColumn:
  21. name: ted_txt_id
  22. referencedColumnName: txt_id
  23. onDelete: CASCADE
  24. ted_lng_id:
  25. targetEntity: TranslatorLang
  26. inversedBy: text
  27. joinColumn:
  28. name: ted_lng_id
  29. referencedColumnName: lng_id
  30. onDelete: CASCADE
  31. lifecycleCallbacks: { }

  1. BDK\TranslatorBundle\Entity\TranslatorApp:
  2. type: entity
  3. table: translator.tbl_tap_application
  4. fields:
  5. tap_id:
  6. type: integer
  7. id: true
  8. generator:
  9. strategy: AUTO
  10. tap_name:
  11. type: text
  12. length: null
  13. tap_prefix:
  14. type: text
  15. length: null
  16. tap_desc:
  17. type: text
  18. length: null
  19. oneToMany:
  20. text_body:
  21. targetEntity: TranslatorText
  22. mappedBy: tap_id
  23. indexBy: txt_tap_id
  24. lifecycleCallbacks: { }

Wszystko jest pięknie, dopóki nie chcę zmienić standardowo wygenerowanych zapytań do obsługi listy tekstów.
Zapytanie, którym normalnie coś takiego bym zrobił wygląda następująco:
  1. -- Lista wszystkich tekstów
  2. SELECT * FROM (SELECT * FROM translator.tbl_txt_text, translator.tbl_lng_language) AS a
  3. LEFT JOIN translator.tbl_ted_text_body ON (ted_txt_id=a.txt_id AND ted_lng_id=a.lng_id)

...nie jestem w stanie przełożyć go na DQL albo utworzyć za pomocą klasy QueryBilder.
Kiedy tylko próbuję połączyć tabele, które nie mają połączenia "wprost" podnosi się krzyk, że:
  1. [Semantical Error] line 0, col 106 near 'b': Error: Identification Variable BDK\TranslatorBundle\Entity\TextBody used in join path expression but was not defined before.

Próbowałem połączyć na początek dwie tablice, ale... się nie udało. Kod, który powoduje problem:
  1. $qb = $em->createQueryBuilder();
  2. $qb->add('select', 'a')
  3. ->add('select', 'b')
  4. ->from('BDK\TranslatorBundle\Entity\TranslatorLang', 'a')
  5. ->leftJoin('BDK\TranslatorBundle\Entity\TextBody', 'b');
  6. $query = $qb->getQuery();
  7. $tmp = $query->getResult();

Oczywiście, mogę zrobić to w ten sposób:
  1. $sql = 'SELECT * FROM (SELECT * FROM translator.tbl_txt_text, translator.tbl_lng_language) AS a '
  2. .'LEFT JOIN translator.tbl_ted_text_body ON (ted_txt_id=a.txt_id AND ted_lng_id=a.lng_id)';
  3. $conn = $this->getDoctrine()->getConnection();
  4. $stmt = $conn->executeQuery($sql);
  5. $list_of_texts = $stmt->fetchAll();

Potem dotarłem, do informacji, że DQL najwyraźniej nie obsługuje takich rzeczy. Może jednak znasz rozwiązanie, które pozwoli mi na użycie standardowych rozwiązań w zgodzie z duchem Doctrine2. Chodzi oczywiście o użycie np. pagera KnpPaginatorBundle czy innych temu podobnych. Może użycie jakiegoś widoku? Na razie skończyły mi się pomysły na eleganckie rozwiązanie.
Dlaczego interesuje mnie to zapytanie? Bardzo łatwo wyszukać co jest do tłumaczenia, a to ważne dla przyszłego użytkownika.
slontrabalski
Hej,

Niestety doctrine 2 nie obsługuje subselect w klauzuli from.

http://stackoverflow.com/questions/8047880...-group-by-a-gro

Możesz użyć ResultSetMapping i createNativeQuery

pozdrowienia
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.