Php 在部分查询后获取完整实体

Php 在部分查询后获取完整实体,php,doctrine-orm,zend-framework2,Php,Doctrine Orm,Zend Framework2,我正在开发一个使用Zend Framework 2和Doctrine 2构建的系统 在这个系统中,我正在处理合同部分,其中我需要一个列表,其中包含来自所有合同的一些数据(部分查询),并且我需要填写一个表格,其中包含来自特定合同的所有数据(实体查找) 但是,由于要在表单中填写的合同也是部分查询的结果,因此未在部分查询中加载的属性也不会为查询的实体加载 我简化了数据,仅显示当前问题,真实实体有更多字段: 实体: use Doctrine\ORM\Mapping as ORM; /** * Con

我正在开发一个使用Zend Framework 2和Doctrine 2构建的系统

在这个系统中,我正在处理合同部分,其中我需要一个列表,其中包含来自所有合同的一些数据(部分查询),并且我需要填写一个表格,其中包含来自特定合同的所有数据(实体查找)

但是,由于要在表单中填写的合同也是部分查询的结果,因此未在部分查询中加载的属性也不会为查询的实体加载

我简化了数据,仅显示当前问题,真实实体有更多字段:

实体:
use Doctrine\ORM\Mapping as ORM;

/**
 * ContractSub
 *
 * @ORM\Table(name="contract_sub", indexes={@ORM\Index(name="contract_id", columns={"contract_id"}), @ORM\Index(name="list_pension_start", columns={"list_pension_start_id"}), @ORM\Index(name="list_lease_car_category", columns={"list_lease_car_category_id"}), @ORM\Index(name="created_by_id", columns={"created_by_id"})})
 * @ORM\Entity(repositoryClass="Application\Repository\ContractSubRepository")
 * @ORM\HasLifecycleCallbacks
 */
class ContractSub
{

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

    /**
     *
     * @var \DateTime @ORM\Column(name="start_date", type="date", nullable=false)
     */
    private $startDate;

    /**
     *
     * @var \DateTime @ORM\Column(name="end_date", type="date", nullable=true)
     */
    private $endDate;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set startDate
     *
     * @param \DateTime $startDate            
     *
     * @return ContractSub
     */
    public function setStartDate($startDate)
    {
        $this->startDate = $startDate;

        return $this;
    }

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

    /**
     * Set endDate
     *
     * @param \DateTime $endDate            
     *
     * @return ContractSub
     */
    public function setEndDate($endDate)
    {
        $this->endDate = $endDate;

        return $this;
    }

    /**
     * Get endDate
     *
     * @return \DateTime
     */
    public function getEndDate()
    {
        return $this->endDate;
    }
}
use Doctrine\ORM\EntityRepository;

class ContractSubRepository extends EntityRepository
{

    public function getPartialStuffForTest()
    {
        $oQuery = $this->_em->createQuery('SELECT PARTIAL ContractSub.{id, startDate} 
                                           FROM Application\Entity\ContractSub ContractSub');
        return $oQuery->getResult();
    }
}
use Zend\Mvc\Controller\AbstractActionController;

class ContractController extends AbstractActionController
{
    public function testAction()
    {
        $oEntityManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        $aContracts = $oEntityManager->getRepository('Application\Entity\ContractSub')->getPartialStuffForTest();
        $oContractSub = $oEntityManager->getRepository('Application\Entity\ContractSub')->find(38);
        var_dump($oContractSub->getStartDate());
        var_dump($oContractSub->getEndDate());
        die();
    }
}
存储库:
use Doctrine\ORM\Mapping as ORM;

/**
 * ContractSub
 *
 * @ORM\Table(name="contract_sub", indexes={@ORM\Index(name="contract_id", columns={"contract_id"}), @ORM\Index(name="list_pension_start", columns={"list_pension_start_id"}), @ORM\Index(name="list_lease_car_category", columns={"list_lease_car_category_id"}), @ORM\Index(name="created_by_id", columns={"created_by_id"})})
 * @ORM\Entity(repositoryClass="Application\Repository\ContractSubRepository")
 * @ORM\HasLifecycleCallbacks
 */
class ContractSub
{

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

    /**
     *
     * @var \DateTime @ORM\Column(name="start_date", type="date", nullable=false)
     */
    private $startDate;

    /**
     *
     * @var \DateTime @ORM\Column(name="end_date", type="date", nullable=true)
     */
    private $endDate;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set startDate
     *
     * @param \DateTime $startDate            
     *
     * @return ContractSub
     */
    public function setStartDate($startDate)
    {
        $this->startDate = $startDate;

        return $this;
    }

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

    /**
     * Set endDate
     *
     * @param \DateTime $endDate            
     *
     * @return ContractSub
     */
    public function setEndDate($endDate)
    {
        $this->endDate = $endDate;

        return $this;
    }

    /**
     * Get endDate
     *
     * @return \DateTime
     */
    public function getEndDate()
    {
        return $this->endDate;
    }
}
use Doctrine\ORM\EntityRepository;

class ContractSubRepository extends EntityRepository
{

    public function getPartialStuffForTest()
    {
        $oQuery = $this->_em->createQuery('SELECT PARTIAL ContractSub.{id, startDate} 
                                           FROM Application\Entity\ContractSub ContractSub');
        return $oQuery->getResult();
    }
}
use Zend\Mvc\Controller\AbstractActionController;

class ContractController extends AbstractActionController
{
    public function testAction()
    {
        $oEntityManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        $aContracts = $oEntityManager->getRepository('Application\Entity\ContractSub')->getPartialStuffForTest();
        $oContractSub = $oEntityManager->getRepository('Application\Entity\ContractSub')->find(38);
        var_dump($oContractSub->getStartDate());
        var_dump($oContractSub->getEndDate());
        die();
    }
}
控制器:
use Doctrine\ORM\Mapping as ORM;

/**
 * ContractSub
 *
 * @ORM\Table(name="contract_sub", indexes={@ORM\Index(name="contract_id", columns={"contract_id"}), @ORM\Index(name="list_pension_start", columns={"list_pension_start_id"}), @ORM\Index(name="list_lease_car_category", columns={"list_lease_car_category_id"}), @ORM\Index(name="created_by_id", columns={"created_by_id"})})
 * @ORM\Entity(repositoryClass="Application\Repository\ContractSubRepository")
 * @ORM\HasLifecycleCallbacks
 */
class ContractSub
{

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

    /**
     *
     * @var \DateTime @ORM\Column(name="start_date", type="date", nullable=false)
     */
    private $startDate;

    /**
     *
     * @var \DateTime @ORM\Column(name="end_date", type="date", nullable=true)
     */
    private $endDate;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set startDate
     *
     * @param \DateTime $startDate            
     *
     * @return ContractSub
     */
    public function setStartDate($startDate)
    {
        $this->startDate = $startDate;

        return $this;
    }

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

    /**
     * Set endDate
     *
     * @param \DateTime $endDate            
     *
     * @return ContractSub
     */
    public function setEndDate($endDate)
    {
        $this->endDate = $endDate;

        return $this;
    }

    /**
     * Get endDate
     *
     * @return \DateTime
     */
    public function getEndDate()
    {
        return $this->endDate;
    }
}
use Doctrine\ORM\EntityRepository;

class ContractSubRepository extends EntityRepository
{

    public function getPartialStuffForTest()
    {
        $oQuery = $this->_em->createQuery('SELECT PARTIAL ContractSub.{id, startDate} 
                                           FROM Application\Entity\ContractSub ContractSub');
        return $oQuery->getResult();
    }
}
use Zend\Mvc\Controller\AbstractActionController;

class ContractController extends AbstractActionController
{
    public function testAction()
    {
        $oEntityManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        $aContracts = $oEntityManager->getRepository('Application\Entity\ContractSub')->getPartialStuffForTest();
        $oContractSub = $oEntityManager->getRepository('Application\Entity\ContractSub')->find(38);
        var_dump($oContractSub->getStartDate());
        var_dump($oContractSub->getEndDate());
        die();
    }
}
此输出:

use Doctrine\ORM\Mapping as ORM;

/**
 * ContractSub
 *
 * @ORM\Table(name="contract_sub", indexes={@ORM\Index(name="contract_id", columns={"contract_id"}), @ORM\Index(name="list_pension_start", columns={"list_pension_start_id"}), @ORM\Index(name="list_lease_car_category", columns={"list_lease_car_category_id"}), @ORM\Index(name="created_by_id", columns={"created_by_id"})})
 * @ORM\Entity(repositoryClass="Application\Repository\ContractSubRepository")
 * @ORM\HasLifecycleCallbacks
 */
class ContractSub
{

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

    /**
     *
     * @var \DateTime @ORM\Column(name="start_date", type="date", nullable=false)
     */
    private $startDate;

    /**
     *
     * @var \DateTime @ORM\Column(name="end_date", type="date", nullable=true)
     */
    private $endDate;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set startDate
     *
     * @param \DateTime $startDate            
     *
     * @return ContractSub
     */
    public function setStartDate($startDate)
    {
        $this->startDate = $startDate;

        return $this;
    }

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

    /**
     * Set endDate
     *
     * @param \DateTime $endDate            
     *
     * @return ContractSub
     */
    public function setEndDate($endDate)
    {
        $this->endDate = $endDate;

        return $this;
    }

    /**
     * Get endDate
     *
     * @return \DateTime
     */
    public function getEndDate()
    {
        return $this->endDate;
    }
}
use Doctrine\ORM\EntityRepository;

class ContractSubRepository extends EntityRepository
{

    public function getPartialStuffForTest()
    {
        $oQuery = $this->_em->createQuery('SELECT PARTIAL ContractSub.{id, startDate} 
                                           FROM Application\Entity\ContractSub ContractSub');
        return $oQuery->getResult();
    }
}
use Zend\Mvc\Controller\AbstractActionController;

class ContractController extends AbstractActionController
{
    public function testAction()
    {
        $oEntityManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        $aContracts = $oEntityManager->getRepository('Application\Entity\ContractSub')->getPartialStuffForTest();
        $oContractSub = $oEntityManager->getRepository('Application\Entity\ContractSub')->find(38);
        var_dump($oContractSub->getStartDate());
        var_dump($oContractSub->getEndDate());
        die();
    }
}
object(DateTime)[479]
  public 'date' => string '2015-06-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Amsterdam' (length=16)

null
指示未加载
endDate
,即使我执行了
find
来检索完整的实体。 当我注释执行
getpartialstuffortest()
的行时,我也会得到
endDate


因此,我想知道是否有任何方法可以强制Doctrine在已缓存部分实体版本后检索完整实体?

要完全加载部分实体,必须使用
$entityManager->refresh($object)

你的答案是正确的

部分对象的使用很棘手。未从数据库中检索到的字段将不会被
UnitOfWork
更新,即使它们在对象中发生了更改。只能通过调用
EntityManager#refresh()
或带有刷新标志的DQL查询,将部分对象升级为完全加载的对象


谢谢,很抱歉我读了一遍。在我的场景中,这仍然不理想,因为我有时在函数中检索完整实体,而以前没有执行过部分查询,有时检索不需要刷新的完整实体。但至少我现在知道如何在需要时检索完整的实体。:)