如何使用Doctrine ResultSetMapping获取相关实体的集合?

Đur*_*nić 8 doctrine symfony doctrine-orm

我使用Doctrine 2.3.4.和Symfony 2.3.0

我有两个实体:PersonApplication.

当某个人申请工作时,会创建应用程序.

从关系PersonApplicationOneToMany,双向的.

这里使用常规Doctrine文档,我设法只在使用单个实体时才能获得正确的结果集.但是,当我添加连接实体时,我获得了根实体的集合,但加入了错误的相关实体.

换句话说,问题是我得到了一个应用程序集合,但都拥有相同的Person.

原生sql查询,直接执行时返回正确的结果.

这是代码:

$sql = "SELECT a.id, a.job, p.first_name, p.last_name 
        FROM application a 
          INNER JOIN person p ON a.person_id = p.id";

    $rsm = new ResultSetMapping;

    $rsm->addEntityResult('\Company\Department\Domain\Model\Application', 'a');
    $rsm->addFieldResult('a','id','id');
    $rsm->addFieldResult('a','job','job');

    $rsm->addJoinedEntityResult('\Company\Department\Domain\Model\Person' , 'p', 'a', 'person');

    $rsm->addFieldResult('p','first_name','firstName');
    $rsm->addFieldResult('p','last_name','lastName');

    $query = $this->em->createNativeQuery($sql, $rsm);

    $result = $query->getResult();

    return $result;
Run Code Online (Sandbox Code Playgroud)

以下是实体类:

namespace Company\Department\Domain\Model;


use Doctrine\ORM\Mapping as ORM;


/**
* Person
*
* @ORM\Entity
* @ORM\Table(name="person")
*/

class Person
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string First name
 *
 * @ORM\Column(name="first_name",type="string",length=255)
 */
private $firstName;

/**
 * @var string Last name
 *
 * @ORM\Column(name="last_name",type="string",length=255)
 */
private $lastName;

/**
*
* @var Applications[]
* @ORM\OneToMany(targetEntity="Application", mappedBy="person")
*/
private $applications;
Run Code Online (Sandbox Code Playgroud)

申请类:

namespace Company\Department\Domain\Model;


use Doctrine\ORM\Mapping as ORM;



/**
* Application (Person applied for a job)
*
* @ORM\Entity
* @ORM\Table(name="application")
*/

class Application
{

/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
 private $id;

/**
 * @var Person
 *
 * @ORM\ManyToOne(targetEntity="Person", inversedBy="applications")
 * @ORM\JoinColumn(name="person_id", referencedColumnName="id")
 */
private $person;


/**
 * @var string
 * @ORM\Column(name="job",type="string", length=100)
 */
private $job;
Run Code Online (Sandbox Code Playgroud)

我一定错过了什么?

Đur*_*nić 6

找出错误的位置:

Person->id物业也必须进行映射.此外,SELECT子句中的列顺序必须与addFieldResult()语句的顺序匹配.

因此,$sql应该是这样的:

SELECT a.id, a.job, p.id AS personId, p.first_name, p.last_name 
FROM application a 
    INNER JOIN person p ON a.person_id=p.id
Run Code Online (Sandbox Code Playgroud)

并映射相关属性,如下所示:

    $rsm->addJoinedEntityResult('\Company\Department\Domain\Model\Person' , 'p', 'a', 'person');
    $rsm->addFieldResult('p','personId','id');
    $rsm->addFieldResult('p','first_name','firstName');
    $rsm->addFieldResult('p','last_name','lastName');
Run Code Online (Sandbox Code Playgroud)

因此,映射的字段结果列名称对应于sql结果列名称,id在这种情况下,第三个参数应该是属性实际名称.