エンティティを更新しているときにコレクションをフィルタリングしたい場合がよくありますが、新しいエンティティは必要ありません。
これは実用的なソリューションです。これはコントローラー(CRUD)の例です。
public function updateAction($id)
{
$service = $this->getServiceRepository()->loadOne('id', $id);
$this->checkPermission($service);
$this->filterInventoryByPrimaryLocation($service);
if($this->getFormHandler()->process('service_repair_service', $service, array('type' => 'update')))
{
$this->getEntityManager()->process('persist', $service);
return $this->render('ServiceRepairBundle:Service:form_message.html.twig', [
'message' => $this->trans('Service has been updated successfully.')
]);
}
return $this->render('ServiceRepairBundle:Service:form.html.twig', [
'form' => $this->getFormHandler()->getForm()->createView(),
]);
}
private function filterInventoryByPrimaryLocation(Service $service)
{
$inventory = $service->getInventory();
$criteria = Criteria::create()
->where(Criteria::expr()->eq('location', $this->getUser()->getPrimaryLocation()))
->orderBy(array('timeInsert' => Criteria::ASC));
$service->setInventory($inventory->matching($criteria));
}
$service = ENTITY、$inventory = ArrayCollection ( $service->getInventory() )
ここでの鍵は、Doctrine の基準を使用することです。詳細はこちら:
http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#filtering-collections
また、エンティティ自体で Criteria を移動することも考えて、そこにパブリック メソッドを作成します。データベースからロードすると、doctrine の postLoad ライフサイクル コールバックを使用してそのメソッドを起動できます。もちろん、サービスなどを必要としない場合は、エンティティに入れることで機能します。
別の解決策は、フォーム内でのみフィルタリングする必要がある場合は、フォーム クラス内のフォーム イベントで Criteria を移動することです。
コレクションのフィルタリングをプロジェクト全体で透過的に行う必要がある場合は、doctrine リスナーを作成し、コードを postLoad() メソッド内に配置します。doctrine リスナーに依存関係を注入することもできますが、循環的なサービス参照を取得しないように、他のサービスを遅延ロードするため、コンテナー自体を注入することをお勧めします。
幸運を!