Php 如何过滤实体关系以返回主对象,但不返回相关对象?(Symfony2/Doctrine2)

Php 如何过滤实体关系以返回主对象,但不返回相关对象?(Symfony2/Doctrine2),php,symfony,doctrine,Php,Symfony,Doctrine,我正在尝试在Symfony2中实现软删除功能。它主要是工作方式,我想,但我有一点麻烦与相关实体的。对于非关键数据,我希望能够软删除相关实体,但仍保留所有数据 例如,假设我有一个账户实体和一个城市实体,其表结构如下: table: account --------------------------- id | account_name | city_id --------------------------- 1 | Jane Doe | 1 2 | John Smith | 1

我正在尝试在Symfony2中实现软删除功能。它主要是工作方式,我想,但我有一点麻烦与相关实体的。对于非关键数据,我希望能够软删除相关实体,但仍保留所有数据

例如,假设我有一个账户实体和一个城市实体,其表结构如下:

table: account
---------------------------
id | account_name | city_id
---------------------------
1  | Jane Doe     | 1
2  | John Smith   | 1
3  | Dave Jones   | 2


table: city
---------------------------
id | city_name | deleted
---------------------------
1  | Phoenix   | 1
2  | New York  | 0
因此,在本例中,“Phoenix”已被软删除,account表中的两行保留了该链接。这样,就可以取消删除Phoenix,并且不会丢失数据

显然,如果Phoenix已经被软删除,我不想在查看帐户时显示这些数据。我已经创建了一个条令过滤器,它将过滤掉
deleted=1
的行。但是,由于Account表中的链接列仍然存在,它实际上指向一个不存在的相关对象(Phoenix),因此抛出EntityNotFoundException

这是我的问题。如何在保留两个对象之间的链接的同时,仍然显示带有软删除城市的帐户列表

在我看来,当查看帐户列表时,应该会产生如下结果:

Account Name | City
---------------------------
Jane Doe     | -
John Smith   | -
Dave Jones   | New York
作为一个快速的实验,我尝试捕获EntityNotFoundException并返回数据。这似乎是我想要的,但这是一个相当丑陋的黑客,将不得不重复各地(除非有另一种方式,我不知道)。下面是我测试的SonataAdmin CRUDController的一个示例:

try {
    return $this->render($this->admin->getTemplate('list'), array(
        'action'   => 'list',
        'form'     => $formView,
        'datagrid' => $datagrid
    ));
} catch (\Twig_Error_Runtime $e) {
    if (strpos($e->getMessage(), 'Entity was not found')) {
        return $this->render($this->admin->getTemplate('list'), array(
            'action'   => 'list',
            'form'     => $formView,
            'datagrid' => $datagrid
        ));
    }
}
我对这个解决方案不满意;我觉得我错过了一条更好的路

作为记录,这是我的过滤器:

class SoftDeleteFilter extends SQLFilter
{
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {
        if (!$targetEntity->hasField('deleted')) {
            return '';
        }

        return $targetTableAlias . '.deleted = false';
    }
}

提前谢谢

这是一个已知的教义局限性,它是

不幸的是,不使用这种模式,而是将delete标志作为业务逻辑进行管理,如下所示:

class Employee
{
    // ...
    private $manager; // soft-deleted to-one association
    public function getManager()
    {
        return $this->manager && $this->manager->active() ? $manager : null;
    }
}

class Manager
{
    // ...
    private $deleted; // soft-delete flag, mapped as datetime|null
    public function active()
    {
        return ! $this->deleted;
    }
}

我还没有尝试过你想要完成的事情,但是我建议你考虑一下查询应该是什么样子。在我看来,与city表的连接应该是这样的
左连接city为c ON c.id=someAlias.city\u id和c.deleted!=1
。如果你能够构造这种
leftJoin
,那么你应该能够解决这个问题。我刚刚查看了查询,它已经是这样了。你不能在管理上下文中使用SoftDeleteFilter吗?这两种方式都不起作用。我使用基本的EntityManager功能进行了尝试,但它抛出了相同的异常。