5

Softdelete の動作は、次のコードのように、エンティティ マネージャーを介して delete ステートメントを実行すると正常に動作します。

$entity = $this->em->getRepository('Users')->find(7);
$this->em->remove($entity);
$this->em->flush();

ただし、QueryBuilder を介して同じ機能を実行すると、データベースでハード削除が実行されます

$qb = $this->em->createQueryBuilder();
$qb->delete('Users', 'p');
$qb->where($qb->expr()->eq('p.id', ':id'));
$qb->setParameters(array("id" => 7));
$result = $qb->getQuery()->getResult();

エンティティマネージャーまたはクエリビルダーを介して、すべての場合にソフト削除を許可するにはどうすればよいですか

4

2 に答える 2

11

DQL を使用する場合は、クエリ ヒントを使用する必要があります。これでうまくいくはずです:

$query = $qb->getQuery()

$query->setHint(
    \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
    'Gedmo\SoftDeleteable\Query\TreeWalker\SoftDeleteableWalker'
);

$result = $query->getResult();

アップデート:

ドキュメントには、クエリヒントを使用する必要があると記載されていますが、例は提供されていないため、テストから使用法を引き出しました。

ドキュメント: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/softdeleteable.md

テストの使用: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/tests/Gedmo/SoftDeleteable/SoftDeleteableEntityTest.php

于 2013-07-16T19:47:22.800 に答える
0

@Ken Hannelによる以前の回答後の私の古い解決策は次のとおりです。

編集: /vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php

walkDeleteClause 関数を次のように置き換えます。

 public function walkDeleteClause(AST\DeleteClause $deleteClause)
    {
        $class = $this->em->getClassMetadata($deleteClause->abstractSchemaName);
        $tableName = $class->getTableName();
        $sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform);
        $this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable);
        $this->rootAliases[] = $deleteClause->aliasIdentificationVariable;
        //check if SoftDeleteableListener is attached 
        foreach ($this->em->getEventManager()->getListeners() as $eventName => $listeners) {
            foreach ($listeners as $listener) {
                if ($listener instanceof \Gedmo\SoftDeleteable\SoftDeleteableListener) {
                    $date = date('Y-m-d H:i:s');
                $sql = 'UPDATE ' . $this->quoteStrategy->getTableName($class, $this->platform) . " SET deletedAt = ' " . $date . " ' ";
                }
            }
        }
        return $sql;
    }

でも本当に、ケン・ハネルのやり方はよりプロフェッショナルで標準的だと思います。

于 2013-07-29T15:55:55.873 に答える