使用Doctrine向后遍历OneToOne表实体的优雅方式

时间:2013-09-17 21:35:00

标签: php doctrine-orm

我有一个非常简单的结构化实体,其中包含一个简单的关联

Database_Entity_Tenant

id         (primary key)
parentId   (id of the parent entry)
code       (a simple identifier for the tenant, unique)

我相应地在我的实体中定义了parentId:

/**  
 * @Column(type="integer")
 * @OneToOne(targetEntity="Tenant")
 * @JoinColumn(name="parentTenantId", referencedColumnName="id")
 * **/
 protected $parentId;

这很好用 - 生成的数据库模式类似于我的选择和它的好处。

现在我正在编写我的第一个方法,它基本上必须以相反的顺序返回所有链接在一起的租户的数组(我使用它来向后走过一系列租户)。

为了做到这一点,我提出了使用while()循环的想法。

$currentTenant = {DATABASE_ENTITY_TENANT}; // In my real code i fetch the entity object of the current tenant

$chain[] = $currentTenant; 

$repository = Database::entityManager()->getRepository('Database_Entity_Tenant');

while(!$currentTenant->getParentId()){
    $currentTenant = $repository->findOneBy(array(
        'id' => $currentTenant->getParentId()
    ));
    $chain[] = $currentTenant;
}

任何没有父级的租户(例如基础租户)都没有父级ID(或null),因此会结束while循环。

现在这一切都可行,但对我来说似乎非常粗糙。我对Doctrine很新,所以我对此并不了解,但我确信有更好的方法可以做到这一点。

问题

Doctrine 2是否为我提供了一套可以用来更好地解决上述问题的功能?

如果没有,那么还有其他方法更优雅吗?

1 个答案:

答案 0 :(得分:0)

如果我的问题没有出错,您只需找到parentId订购的关联表中的所有条目。在Doctrine2中,您可以执行以下操作:

$currentTenant = {DATABASE_ENTITY_TENANT}; // assuming a valid entity

$repository = Database::entityManager()
    ->getRepository('Database_Entity_Tenant')
    ->createQueryBuilder('t')
    ->where('t.parentId IS NOT NULL')
    ->andWhere('t.parentId < :current') /* < or > */
    ->setParameter('current', $currentTenant->getParentId()->getId())
    ->orderBy('t.parentId', 'ASC') /* ASC or DESC, no array_reverse */
    ->getQuery()
    ->getResult();

/* At this point $repository contains all what you need because of Doctrine,
 * but if you want a chain variable: */

$chain = array();
foreach ($repository as $tenant) {
    $chain[] = $tenant->getCode(); // your tenant entity if your entity is mapped correctly
}

希望这有帮助!