当你更新一个实体时,你经常想要过滤集合,而不是一个新的,对吧?
这是一个可行的解决方案,这是来自控制器(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's Criteria,更多信息在这里:
http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#filtering-collections
还可以考虑将 Criteria 移动到实体本身,在那里创建一个公共方法。当您从数据库加载它时,您可以使用学说的 postLoad 生命周期回调触发该方法。如果您不需要任何服务或类似的东西,当然将其放入实体中会起作用。
如果您只需要在表单内进行过滤,则另一种解决方案可能是在 Form 类内的 Form Event 中移动 Criteria。
如果您需要在整个项目中透明地完成集合过滤,请编写一个学说监听器并将代码放在 postLoad() 方法中。您也可以在学说监听器中注入依赖项,但我建议注入容器本身,因为延迟加载其他服务,所以您不会得到循环服务引用。
祝你好运!