Symfony:从API延迟加载关系

时间:2019-05-09 05:14:06

标签: symfony doctrine symfony4 api-platform.com

我正在寻找最好的方法来从API延迟加载与实体的关系。

场景 我有一个Symfony 4应用程序,该应用程序使用Doctrine支持数据库,在该数据库中,我有许多表,包括Customer。

我还可以访问API,该API包含与该客户有关的不同数据,例如发票,帐户,产品,账单。

我需要显示有关客户的分页数据列表,其中包含来自Customer和AP​​I查询结果的值。

到目前为止,我的解决方案是在Customer实体上为API中的每个相关实体创建一个属性,然后我有一个EntityLoadListener类来侦听PostLoad事件生命周期事件。触发后,它会检查实体是否为客户,如果是,则从API加载结果并更新关系:

// customer is the customer entity
// the api call here returns a collection full of invoice entities
$invoices = $this->api->getInvoicesForAccount($customer->getAccountCode());

// get the name of the property to set on the entity
$propertyName = 'apiInvoices';

// set the property on the entity
$relationProp = $em->getClassMetadata($class)
  ->reflClass->getProperty($propertyName);
$relationProp->setAccessible(true);
$relationProp->setValue($entity, $invoices);

这有效,但是在加载大量客户时,速度很慢。而且,如果我不需要显示发票数据,则宁愿不从API加载数据。有没有更好的方法来实现此目的,我只在调用Customer getter的getApiInvoices(即延迟加载)时查询API?

1 个答案:

答案 0 :(得分:0)

我相信APIP默认使用预先加载。您可以通过在yaml文件中进行配置来使用延迟加载

# api/config/packages/api_platform.yaml
api_platform:
    eager_loading:
        force_eager: false

或在资源和操作级别:

<?php
// api/src/Entity/User.php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ApiResource(attributes={"force_eager"=false})
 * @ORM\Entity
 */
class User
{
    /**
     * @var Address
     *
     * @ORM\ManyToOne(targetEntity="Address", fetch="EAGER")
     */
    public $address;

    /**
     * @var Group[]
     *
     * @ORM\ManyToMany(targetEntity="Group", inversedBy="users")
     * @ORM\JoinTable(name="users_groups")
     */
    public $groups;

    // ...
}

https://api-platform.com/docs/core/performance/#force-eager