Ankündigung

Einklappen
Keine Ankündigung bisher.

Symfony Doctrine ManyToMany Abfrage

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Symfony Doctrine ManyToMany Abfrage

    Hi.

    Ich habe ein kleines Verständnisproblem bei dem mir sicherlich jemand helfen kann.

    Ich habe eine Benutzertabelle. Jeder Benutzer kann ein oder mehreren Gruppen zugeordnet werden.

    Dann gibt es eine Entity von Produkten. der User darf dann alle Produkte der Gruppe sehen die er zugeordnet ist.

    Also ManyToMany User<->Gruppen
    ManyToOne Produkte<->Gruppe

    Nun weiß ich nicht wie ich die Doctrineabfrage aufbauen soll:

    PHP-Code:
    $Ergebnis $repo->createQueryBuilder 'a' )
                    ->
    where 'a.gruppe= :Gruppe' )
                    ->
    setParameter "Gruppe"$this->getUser ()->getGruppe () )
                    ->
    orderBy 'a.lookupSet''DESC' ); 
    würde das so gehen? In SQL würde das ja so nicht hinkommen ohne Array abfrage.

    Danke für ein paar Infos.
    * * * * COMMODORE C64 BASIC V2 * * * *
    64K RAM SYSTEM 38911 BASIC BYTES FREE
    READY

  • #2
    Hallo,

    das ist natürlich etwas wenig Kontext. Zeige uns doch mal Deine Doctrine Models.

    Deiner Erklärung entnehme ich, dass Du mehrere inner joins brauchst für die Benutzer => Gruppe => Produkte Zuordnung. Also in etwa so (in Deinem User Repository):
    PHP-Code:
        public function getGroupProducts($group) {     return $this->entityManager->createQueryBuilder('user')         ->select('user.*, group.name, user.name, product.name')         ->innerJoin('user.group''group')         ->innerJoin('group.product''product')         ->where('group.name = :name')         ->setParameter('name'$group)         ->orderBy('user.lookupSet''DESC')         ->getQuery()         ->getResult(AbstractQuery::HYDRATE_OBJECT); } 
    Sollte so funktionieren. Wegen Perfomance Optimierungen kannst Du auch nochmal einen leftJoin ausprobieren. Wobei ich mir jetzt aber nicht sicher bin, ob Dir der leftJoin wirklich nur die verknüpften Daten anzeigt. Ansonsten kann ich Dir noch folgendes Tutorial empfehlen: http://knpuniversity.com/screencast/doctrine-relations

    PS: Du musst von jeder Tabelle, die Du joinst auch mindestens eine Spalte in Deinem SELECT verwenden. Das muss bei Doctrine so sein. Ob Du mit den Daten dann weiterarbeitest oder nicht, ist völlig unerheblich.


    MFG

    derwunner

    Kommentar


    • #3
      Ja, so ist es. Das war die Lösung. Ich muss mich bis zum User im Endeffekt "runter joinen" dann brauche ich nur die User_id anzugeben und es klappt.

      Vielen Dank!
      * * * * COMMODORE C64 BASIC V2 * * * *
      64K RAM SYSTEM 38911 BASIC BYTES FREE
      READY

      Kommentar


      • #4
        Wenn dich lediglich die Produktdaten interessieren, empfiehlt es sich, eine Entität für die Join-Tabelle zu erstellen (bspw. GroupsUsersJoinTable). Damit lassen sich unnötige JOINs einsparen (bspw. der auf die Users- oder Groups-Tabelle), die Doctrine ansonsten automatisch generiert. Das könnte dann in etwa so aussehen:

        PHP-Code:
        <doctrine-mapping>
            <
        entity name='..\Entity\GroupsUsersJoinTable' table='groups_users'>

                <
        id name='GroupId' type='integer' />
                <
        id name='UserId' type='integer' />

                <
        many-to-one field='Group' target-entity='rckd\Entity\Group'>
                    <
        join-column name='GroupId' referenced-column-name='Id' />
                </
        many-to-one>
                <
        many-to-one field='User' target-entity='rckd\Entity\User'>
                    <
        join-column name='UserId' referenced-column-name='Id' />
                </
        many-to-one>

            </
        entity>
        </
        doctrine-mapping
        PHP-Code:
        # ..\Entity\GroupsUsersJoinTable.php

        class GroupsUsersJoinTable{
            public 
        $GroupId null;
            public 
        $UserId null;

            public 
        $Group null;
            public 
        $User null;

        PHP-Code:
        $products $em->createQueryBuilder()
            ->
        select('p.Name')

            ->
        from(Product::class, 'p')

            ->
        join(GroupsUsersJoinTable::class, 'gu''WITH''gu.Group = p.Group')
            ->
        where('gu.UserId = :UserId')

            ->
        setParameter('UserId'1)
            ->
        getQuery()
            ->
        getResult(); 
        Dies erzeugt folgendes SQL-Statement:

        PHP-Code:
        SELECT
            p
        .Name

        FROM
            products p

        INNER JOIN
            groups_users gu ON gu
        .GroupId p.GroupId

        WHERE
            gu
        .UserId = ? 
        ---

        Zum Vergleich:

        PHP-Code:
        $products $em->createQueryBuilder()
            ->
        select('p.Name')

            ->
        from(Product::class, 'p')
            ->
        join('p.Group''g')
            ->
        join('g.Users''u')

            ->
        where('u.Id = :UserId')

            ->
        setParameter('UserId'1)
            ->
        getQuery()
            ->
        getResult(); 
        ..erzeugt folgendes SQL-Statement:

        PHP-Code:
        SELECT
            p
        .Name

        FROM
            products p

        INNER JOIN 
        # <-
            
        groups g ON g.Id p.GroupId

        INNER JOIN
            groups_users gu ON gu
        .GroupId g.Id

        INNER JOIN 
        # <-
            
        users u ON u.Id gu.UserId

        WHERE
            u
        .Id = ? 
        Ich bin mir nicht sicher ob man Doctrine anweisen kann, das zu unterlassen. Mir fällt da spontan keine Möglichkeit ein.

        ---

        Zitat von derwunner Beitrag anzeigen
        PS: Du musst von jeder Tabelle, die Du joinst auch mindestens eine Spalte in Deinem SELECT verwenden. Das muss bei Doctrine so sein. Ob Du mit den Daten dann weiterarbeitest oder nicht, ist völlig unerheblich.
        Nope.
        [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

        Kommentar


        • #5
          Zitat von lottikarotti Beitrag anzeigen

          Ich bin mir nicht sicher ob man Doctrine anweisen kann, das zu unterlassen. Mir fällt da spontan keine Möglichkeit ein.

          ---


          Nope.
          Ich wenn nicht schon 20 mal damit auf die Schnautze gefallen wäre, das Internet stundenlang danach durchsucht hätte und mir tonnenweise SO Beiträge dazu gegeben hätte, dann würde ich Dir recht geben. Leider ist es wirklich so. Mir scheint auch nicht, als hättest Du es ausprobiert.

          Kommentar


          • #6
            Zitat von derwunner Beitrag anzeigen
            Ich wenn nicht schon 20 mal damit auf die Schnautze gefallen wäre, das Internet stundenlang danach durchsucht hätte und mir tonnenweise SO Beiträge dazu gegeben hätte, dann würde ich Dir recht geben. Leider ist es wirklich so. Mir scheint auch nicht, als hättest Du es ausprobiert.
            Nope. Das ist Blödsinn. Ich nutze Doctrine täglich. Die oben gezeigten Beispiele sind von mir getestet und lauffähig. Die daraus resultierenden SQL-Statements sind mit dem EchoSQLLogger ermittelt.
            [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

            Kommentar

            Lädt...
            X