2014-03-13 114 views
1

我有三個表 1)產品類別(一個類別可以有很多產品) 2)產品(一個產品應該屬於一個類別,可以有0或多個圖像) 3)產品圖片(一個圖像應該屬於一個產品)Doctrine2一對多/多對一的關係給出重複的記錄

現在我想從偏移0 施加8的限制的產品有6種產品在我的數據庫。 我想要的是每個產品都有類別和圖像的細節。爲此我使用了doctrine 2關聯映射。

我的實體如下: -

<?php 

    namespace Nitin\TestBundle\Entity; 

    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * Nitin\TestBundle\Entity\Product 
    * 
    * @ORM\Table(name="product", indexes={@ORM\Index(name="fk_product_cat", columns={"fk_product_cat"})}) 
    * @ORM\Entity(repositoryClass="Nitin\TestBundle\Repository\ProductRepository") 
    */ 
    class Product 
    { 
     /** 
     * @var integer 
     * 
     * @ORM\Column(name="id", type="integer", nullable=false) 
     * @ORM\Id 
     * @ORM\GeneratedValue(strategy="IDENTITY") 
     */ 
     private $id; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="product_title", type="string", length=250, nullable=false) 
     * @Assert\NotBlank(message = "Please enter valid product title.") 
     */ 
     private $productTitle; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="description", type="text", nullable=true) 
     */ 
     private $description; 

     /** 
     * @var float 
     * 
     * @ORM\Column(name="price", type="float", precision=10, scale=0, nullable=false) 
     * @Assert\NotBlank 
     * Assert\Type(type="float", message="The value should have decimal points.") 
     */ 
     private $price; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(name="created_date", type="datetime", nullable=false) 
     */ 
     private $createdDate; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(name="modified_date", type="datetime", nullable=false) 
     */ 
     private $modifiedDate; 

     /** 
     * @var boolean 
     * 
     * @ORM\Column(name="featured", type="boolean", precision=0, scale=0, nullable=false, unique=false) 
     */ 
     private $featured; 

     /** 
     * @var \Nitin\TestBundle\Entity\ProductCategory 
     * 
     * @ORM\ManyToOne(targetEntity="Nitin\TestBundle\Entity\ProductCategory", cascade={"persist", "remove"}) 
     * @ORM\JoinColumns({ 
     * @ORM\JoinColumn(name="fk_product_cat", referencedColumnName="id", onDelete="CASCADE") 
     * }) 
     * @Assert\NotBlank(message = "Please Select Product Category.") 
     */ 
     private $fkProductCat; 

     /** 
     * @var \Doctrine\Common\Collections\Collection 
     * 
     * @ORM\OneToMany(targetEntity="Nitin\TestBundle\Entity\ProductImages", mappedBy="fkProduct", cascade={"persist"}) 
     * 
     */ 
     private $images; 

代碼產品類別實體是: -

<?php 

    namespace Nitin\TestBundle\Entity; 

    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * Nitin\TestBundle\Entity\ProductCategory 
    * 
    * @ORM\Table(name="product_category", indexes={@ORM\Index(name="fk_parent", columns={"fk_parent"})}) 
    * @ORM\Entity(repositoryClass="Nitin\TestBundle\Repository\ProductCategoryRepository") 
    */ 
    class ProductCategory 
    { 
     /** 
     * @var integer 
     * 
     * @ORM\Column(name="id", type="integer", nullable=false) 
     * @ORM\Id 
     * @ORM\GeneratedValue(strategy="IDENTITY") 
     */ 
     private $id; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="category_name", type="string", length=250, nullable=false) 
     * @Assert\NotBlank 
     */ 
     private $categoryName; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="description", type="text", nullable=false) 
     */ 
     private $description; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(name="created_date", type="datetime", nullable=true) 
     */ 
     private $createdDate; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(name="modified_date", type="datetime", nullable=false) 
     */ 
     private $modifiedDate; 

     /** 
     * @var \Nitin\TestBundle\Entity\ProductCategory 
     * 
     * @ORM\ManyToOne(targetEntity="Nitin\TestBundle\Entity\ProductCategory", cascade={"persist", "remove"}) 
     * @ORM\JoinColumns({ 
     * @ORM\JoinColumn(name="fk_parent", referencedColumnName="id", onDelete="CASCADE") 
     * }) 
     */ 
     private $fkParent; 

     /** 
     * @var \Doctrine\Common\Collections\Collection 
     * 
     * @ORM\OneToMany(targetEntity="Nitin\TestBundle\Entity\ProductCategory", mappedBy="fkParent", cascade={"persist"}) 
     */ 
     private $child; 

代碼產品圖片實體是

<?php 

    namespace Nitin\TestBundle\Entity; 

    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\HttpFoundation\File\UploadedFile; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * ProductImages 
    * 
    * @ORM\Table(name="product_images", indexes={@ORM\Index(name="fk_product", columns={"fk_product"})}) 
    * @ORM\Entity 
    * @ORM\HasLifecycleCallbacks 
    */ 
    class ProductImages { 

     /** 
     * @var integer 
     * 
     * @ORM\Column(name="id", type="integer", nullable=false) 
     * @ORM\Id 
     * @ORM\GeneratedValue(strategy="IDENTITY") 
     */ 
     private $id; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="title", type="string", length=255, nullable=false) 
     */ 
     private $title; 

     /** 
     * @ORM\Column(type="string", length=255, nullable=true) 
     */ 
     private $path; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(name="created_date", type="datetime", nullable=false) 
     */ 
     private $createdDate; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(name="modified_date", type="datetime", nullable=false) 
     */ 
     private $modifiedDate; 

     /** 
     * @var \Nitin\TestBundle\Entity\Product 
     * 
     * @ORM\ManyToOne(targetEntity="Nitin\TestBundle\Entity\Product", inversedBy="id", cascade={"merge", "remove"}) 
     * @ORM\JoinColumns({ 
     * @ORM\JoinColumn(name="fk_product", referencedColumnName="id", onDelete="CASCADE") 
     * }) 
     */ 
     private $fkProduct; 

     /** 
     * @Assert\File(maxSize="6000000") 
     */ 
     private $file; 

爲了獲得結果,我通過存儲庫中的自定義函數使用Doctrine查詢生成器: -

  <?php 

    namespace Nitin\TestBundle\Repository; 

    use Doctrine\ORM\EntityRepository; 

    /** 
    * ProductRepository 
    * 
    * This class was generated by the Doctrine ORM. Add your own custom 
    * repository methods below. 
    */ 
    class ProductRepository extends EntityRepository { 
    public function getAllProduct($offset = 0, $limit = 10, $arrayResult = true) { 
      $qb = $this->_em->createQueryBuilder(); 

      $qb->select(array('p', 'pc', 'img')) 
        ->from($this->_entityName, 'p') 
        ->leftJoin('p.fkProductCat', 'pc') 
        ->leftJoin('p.images', 'img') 
        //->add('where ', $qb->expr()->countDistinct('p.id')) 
        ; 


      //Pagination logic 
      $from = (int) $offset; 
      $start = ($from == 1) ? ($from - 1) : (($from - 1) * $limit); 
      $start = ($start < 0) ? 0 : $start; 
      $qb->setFirstResult($start); 
      $qb->setMaxResults($limit); 
      //echo $qb->getQuery()->getSQL();die; 
      if (TRUE === $arrayResult) { 
       return $qb->getQuery()->getArrayResult(); 
      } 
      return $qb->getQuery()->getResult(); 
     } 

,並呼籲在控制器這樣的功能: -

<?php 

    namespace Nitin\TestBundle\Controller; 

    use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

    class IndexController extends Controller 
    { 
     private $data = array(); 

     public function indexAction() 
     { 
      $em = $this->getDoctrine()->getEntityManager(); 
      $this->data['latestProduct'] = $em->getRepository('BitcoinAdminBundle:Product')->getAllProduct(0, 8); 

      return $this->render('BitcoinSiteBundle:Default:index.html.twig', $this->data); 
     } 
    } 

我期待着6條,但只獲得了3。當我嘗試打印SQL和運行在我的分貝該查詢,我發現查詢返回重複記錄。

所以,任何人都可以提出我犯了錯誤的地方。

感謝

回答

1

嘗試setMaxResults();之後加入return $paginator = new Paginator($qb->getQuery, $fetchJoinCollection = true);。加入收藏時,這是一個常見問題。