首页 文章

Doctrine2 One-To-Many / Many-To-One关系提供重复记录

提问于
浏览
1

我有三个表1)产品类别(一个类别可以有很多产品)2)产品(一个产品应属于一个类别,可以有0或多个图像)3)产品图像(一个图像应属于一个产品)

现在我想让产品从偏移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并在我的db中运行该查询时,我发现查询返回重复记录 .

所以,任何人都可以建议我犯错的地方 .

谢谢

1 回答

  • 1

    尝试在 setMaxResults(); 之后添加 return $paginator = new Paginator($qb->getQuery, $fetchJoinCollection = true); . 加入集合时这是一个常见问题 .

相关问题