如何在Doctrine 2中扩展存储库?用于分享不同表名中的共同功能?

时间:2017-08-28 15:27:19

标签: php symfony doctrine-orm doctrine symfony-3.3

我一直在研究这个话题,但到目前为止,我找不到任何有用的方案。

简要说明:我有两个表Quote(表名:quote)和QuoteArchive(表名:quote_archive)。两者共享完全相同的列和类型。据我所知,此转为Doctrine MappedSuper Class例如:MappedSuperclassQuote

之后,QuoteQuoteArchive实体将从MappedSuperclassQuote延伸,并且两者将共享完全相同的结构。

Quote有一个带有一些功能的自定义存储库。 QuoteArchive需要与Quote完全相同的存储库功能,唯一的区别是表名和PK。

在这种情况下我有两个疑问:

  • 如果子类中的PK(@Id)不同,如何扩展Doctrine实体?
  • 当唯一的更改是表名时,如何在实体之间扩展或共享相同的存储库。

为了更好地了解这是我当前实体的样子:

/**
 * @ORM\Entity
 * @ORM\Table(name="quote")
 * @ORM\Entity(repositoryClass="QuoteBundle\Entity\Repository\QuoteRepository")
 */
class Quote
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer",unique=true,nullable=false)
     * @ORM\GeneratedValue
     */
    private $quoteId;

    // ...
}

/**
 * @ORM\Entity
 * @ORM\Table(name="quote_archive")
 * @ORM\Entity(repositoryClass="QuoteBundle\Entity\Repository\QuoteArchiveRepository")
 */
class QuoteArchive
{   
    /**
     * @ORM\Id
     * @ORM\Column(type="integer",unique=true,nullable=false)
     */
    private $archiveId;

    // ...
}

最后但并非最不重要:

class QuoteRepository extends EntityRepository
{
    public function getCurrentQuoteId(int $OrigQuoteId)
    {
        $em   = $this->getEntityManager();
        $qb   = $em->createQueryBuilder();

        return $qb->select('q')
                  ->from('QuoteBundle:Quote')
                  ->where('q.origQuoteId =:origQuoteId')
                  ->setParameter('origQuoteId', $OrigQuoteId)
                  ->andWhere('q.quoteType =:quoteType')
                  ->setParameter('quoteType', 'current')
                  ->getQuery()
                  ->getResult();
    }
}

这是什么问题?我需要在QuoteArchiveRepository中重复相同的功能,并将表格从quote更改为quote_archive,这正是我想要尽可能避免的。

有人可以给我一些想法吗?代码示例很棒:)

参考文献:

1 个答案:

答案 0 :(得分:2)

我认为你错误地做了一个MappedSuperclassQuote实体。 你必须从Quote继承档案。

示例:您有Quote实体 定义应该是这样的:

 /**
 * @ORM\Table(name="app_quote")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="quote_type", fieldName="quoteType", type="string")
 * @ORM\DiscriminatorMap({
 *     "quote":"YourBundle\Entity\Quote",
 *     "quote_archive":"YourBundle\Entity\QuoteArchive"
 * })
 * @Gedmo\Loggable
 * @ORM\Entity(repositoryClass="YourBundle\Repository\QuoteRepository")
 */

为什么要加入JOINED?因为你想要两个单独的表(SINGLE_TABLE没有做什么)而且你没有真正的抽象类(因为Quote和QuoteArchive对你来说意味着什么)

之后,你的表QuoteArchive应该扩展第一个:

/**
 * @ORM\Entity
 * @ORM\Table(name="app_quote_archive")
 */
class QuoteArchive extends Quote
{
...
}

app_quote中的列quote_type将帮助您了解这是否是归档引用。

它为您提供所需的一切: - QuoteArchive可以访问QuoteRepository中的函数 - 每个表都有单独的ID

有一件事可能让你烦恼:如果你想设置一个已归档的报价,那么现在在Doctrine中更改实体类型并不容易。在这种情况下,最好使用single_table连接类型。所有数据都存储在数据库中的同一个表中,使类型更改变得容易,但您保留了两个不同的实体。