如何将实体上的外键映射为字段和映射到Doctrine?

时间:2018-05-31 12:38:11

标签: php symfony doctrine-orm doctrine

后台(简短版):Symfony4应用程序,其中我在doctrine实体层上使用自定义数据层,因此业务逻辑层不依赖于数据库模式。目前这不可改变。

在某些情况下,将外键映射为字段更容易使用:

/**
 * @var string
 *
 * @ORM\Column(name="article_id", type="string")
 */
protected $articleId;

但在同一实体的其他情况下,我需要关系:

/**
 * @var Article
 *
 * @ORM\OneToOne(targetEntity="Article")
 * @ORM\JoinColumn(name="article_id", referencedColumnName="id")
 */
protected $article;

在2个副本中没有相同的实体,我在一个单独的类中添加了上面的片段。如果我保持关系,一切运行良好($ articleId被忽略)但如果只提供$ articleId并且$ articles为null,则doctrine将在DB null中插入外键。

1 个答案:

答案 0 :(得分:0)

我找到了一个可能的解决方案:我解析了类元数据,如果在$class->associationMappings['joinColumnFieldNames']中存在我也作为对象中的字段的字段,我删除了关联映射:

  

教义/ ORM / LIB /学说/ ORM / UnitOfWork.php

private function doMerge($entity, array &$visited, $prevManagedCopy = null, array $assoc = [])
{
    $oid = spl_object_hash($entity);

    if (isset($visited[$oid])) {
        $managedCopy = $visited[$oid];

        if ($prevManagedCopy !== null) {
            $this->updateAssociationWithMergedEntity($entity, $assoc, $prevManagedCopy, $managedCopy);
        }

        return $managedCopy;
    }

    $class = $this->em->getClassMetadata(get_class($entity));

    /* Code that I added */
    foreach ($class->associationMappings as $key => $mapping) {
        $joinColumns = $mapping['joinColumnFieldNames'] ?? [];

        if (array_intersect($joinColumns, $class->getColumnNames())) {
            unset($class->associationMappings[$key]);
            unset($class->reflFields[$key]);
        }
    }

    /* .... */

}

做这样的事情符合道德标准吗?