Symfony2 doctrine2 manytomany with union and join

时间:2015-03-18 15:29:46

标签: php symfony doctrine-orm doctrine

SELECT a.*, b.*, c.* 
FROM crm_relationship a 
JOIN contact b ON a.from_contact = b.id 
JOIN crm_relationship_setting c ON a.relationship_id = c.id 
WHERE a.to_contact = '2' AND a.from_contact != '2' 
UNION ALL 
SELECT a.*, b.*, c.* 
FROM crm_relationship a 
JOIN contact b ON a.to_contact = b.id 
JOIN crm_relationship_setting c ON a.relationship_id = c.id 
WHERE a.from_contact = '2' AND a.to_contact != '2'

我有一个表商店联系信息,id,全名等

我有一个表商店关系设置,存储关系名称

我有一个表店关系,fromContact是id引用联系 id,toContact是id引用联系 id和relationId引用关系设置< /强>

所以我想做的是,选择所有关系,无论是来自联系人还是联系人,我认为sql查询解释了。

我已经尝试的是,使用symfony OneToMany,但是只能引用一个字段(contact.id引用relation.fromContact或relation.toContact),我需要它来获取双方

这是我的联系实体的一部分

namespace MPN\DataBundle\Entity\Contact;

use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="ContactRepository")
 * @ORM\Table(name="contact")
 * @ORM\HasLifecycleCallbacks()
 */
class Contact extends BaseModel
{
    /**
     * @var ArrayCollection
     * 
     * @ORM\OneToMany(targetEntity="Eco\Crm\RelationBundle\Entity\Relation", mappedBy="fromContact")
     */
    private $relations;

    public function __construct()
    {
        ////////.........
        $this->relations     = new ArrayCollection();
    }

    //..............

    /**
     * Get relations
     *
     * @return \Doctrine\Common\Collections\Collection
     */
     public function getRelations()
     {
         return $this->relations;
     }

     /**
      * Add relations
      *
      * @param \Eco\Crm\RelationBundle\Entity\Relation $relation
      * @return Contact
      */
      public function addRelations(\Eco\Crm\RelationBundle\Entity\Relation $relation)
      {
          $this->relations[] = $relation;

          return $this;
      }

      /**
       * Remove relations
       *
       * @param \Eco\Crm\RelationBundle\Entity\Relation $relation
       */
      public function removeRelations(\Eco\Crm\RelationBundle\Entity\Relation $relation)
      {
          $this->relations->removeElement($relation);
      }
}

这是我的关系实体的一部分

namespace Eco\Crm\RelationBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * InvoiceItem
 *
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Table(name="crm_relationship")
 */
class Relation
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\ManyToOne(targetEntity="\Eco\Crm\RelationBundle\Entity\Relation", inversedBy="relations")
     * @ORM\JoinColumn(name="from_contact", referencedColumnName="id", nullable=false)
     *
     */
    private $fromContact;

    /**
     * @var integer
     * 
     * @ORM\Column(name="to_contact", type="integer", nullable=false)
     */
    private $toContact;

    /**
     * @ORM\ManyToOne(targetEntity="Eco\Crm\RelationBundle\Entity\RelationSetting", inversedBy="relations")
     * @ORM\JoinColumn(name="relationship_id", referencedColumnName="id", nullable=false)
     */
    private $relationship;

    /**
     * @ORM\Column(name="deleted", type="boolean")
     */
    private $deleted;

    /**
     * @ORM\Column(name="created_at", type="datetime")
     * @Gedmo\Timestampable(on="create")
     */
    private $createdAt;

    /**
     * @ORM\Column(name="updated_at", type="datetime")
     * @Gedmo\Timestampable(on="update")
     */
    private $updatedAt;
/**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set fromContact
     *
     * @param \Eco\Crm\RelationBundle\Entity\Relation $contact
     * @return Contact
     */
    public function setFromContact(\Eco\Crm\RelationBundle\Entity\Relation $contact)
    {
        $this->fromContact = $contact;

        return $this;
    }

    /**
     * Get fromContact
     *
     * @return \Eco\Crm\RelationBundle\Entity\Relation
     */
    public function getFromContact()
    {
        return $this->fromContact;
    }

    /**
     * Set toContact
     *
     * @param \Eco\Crm\RelationBundle\Entity\Relation $contact
     * @return Contact
     */
    public function setToContact(\Eco\Crm\RelationBundle\Entity\Relation $contact)
    {
        $this->toContact = $contact;

        return $this;
    }

    /**
     * Get toContact
     *
     * @return \Eco\Crm\RelationBundle\Entity\Relation
     */
    public function getToContact()
    {
        return $this->toContact;
    }

    /**
     * Set relationship
     *
     * @param \Eco\Crm\RelationBundle\Entity\RelationSetting $relation
     * @return RelationSetting
     */
    public function setRelationship(\Eco\Crm\RelationBundle\Entity\RelationSetting $relation)
    {
        $this->relationship = $relation;

        return $this;
    }

    /**
     * Get relationship
     *
     * @return \Eco\Crm\RelationBundle\Entity\RelationSetting
     */
    public function getRelationship()
    {
        return $this->relationship;
    }

    /**
     * Set deleted
     *
     * @param boolean $deleted
     * @return Contact
     */
    public function setDeleted($deleted)
    {
        $this->deleted = $deleted;

        return $this;
    }

    /**
     * Get deleted
     *
     * @return boolean
     */
    public function getDeleted()
    {
        return $this->deleted;
    }

    /**
     * Check if this setting is soft-deleted.
     *
     * @return Boolean true if this setting is soft-deleted
     */
    public function isDeleted()
    {
        return $this->deleted;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return Invoice
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return Invoice
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }
}

oneToMany解决方案如上所示,但结果不是我想要的,所以我选择 Doctrine Native Query

我在 ContactRepository 中编写查询,这是代码

namespace MPN\DataBundle\Entity\Contact;

use MPN\CRMBundle\Entity\Repository\Repository;
use Doctrine\ORM\Query\ResultSetMapping;

/**
 * ContactRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class ContactRepository extends Repository
{
    /**
     * Find all relations for the contact
     */
    public function findRelatedContact($contactId)
    {
        $rsm = new ResultSetMapping();
//        $dql = "SELECT a, b, c FROM EcoCrmRelationBundle:Relation a 
//                JOIN MPNDataBundle:Contact\Contact b ON a.fromContact = b.id
//                JOIN EcoCrmRelationBundle:RelationSetting c ON a.relationship = c.id
//                WHERE a.toContact = " . $contactId . " AND a.fromContact != " . $contactId . "
//                UNION ALL
//                SELECT a, b, c FROM EcoCrmRelationBundle:Relation a 
//                JOIN MPNDataBundle:Contact\Contact b ON a.toContact = b.id
//                JOIN EcoCrmRelationBundle:RelationSetting c ON a.relationship = c.id
//                WHERE a.fromContact = " . $contactId . " AND a.toContact != " . $contactId;
//        
//        $query = $this->getEntityManager()->createNativeQuery($dql, $rsm);
        $query = $this->getEntityManager()->createNativeQuery("
            SELECT a.*, b.*, c.* FROM crm_relationship a 
            JOIN contact b ON a.from_contact = b.id
            JOIN crm_relationship_setting c ON a.relationship_id = c.id
            WHERE a.to_contact = :cid AND a.from_contact != :cid
            UNION ALL
            SELECT a.*, b.*, c.* FROM crm_relationship a 
            JOIN contact b ON a.to_contact = b.id
            JOIN crm_relationship_setting c ON a.relationship_id = c.id
            WHERE a.from_contact = :cid AND a.to_contact != :cid
            ", $rsm);
        $query->setParameter('cid', $contactId);
        exit(var_dump($query->getResult()));
        try {
            return $query->getArrayResult();
        } catch (DoctrineORMNoResultException $e) {
            return null;
        }
    }
}

但它始终从 findRelatedContact 返回null,我复制粘贴查询并在phpmyadmin中运行正是我想要的工作,我不知道为什么,我的nativeQuery有什么问题吗?或者有没有任何OneToMany,ManyToMany方式没有nativequery?我觉得它有更好的吗?

0 个答案:

没有答案