【问题标题】:How to extend from Doctrine-Entity without Discriminator-Column如何在没有鉴别器列的情况下从 Doctrine-Entity 扩展
【发布时间】:2016-07-08 00:22:02
【问题描述】:

挑战:

我想以这种方式重用具有类继承的第三方捆绑包的现有实体,仍然只剩下一个表,不需要额外的东西。这意味着:没有鉴别器列,也没有 JOIN。 相反,只有最后一个继承最多的类应该是可查询的,向基实体添加一些属性,然后只使用一个包含所有列的表,这些列是从自身添加到实体并通过继承。

这里要明确一点:我不对经典的表继承感兴趣。我只是想用这种方式扩展一个带有附加列的基类,数据库中的表代表所有需要的列的总和。

无需创建基本实体的实例。

有兴趣的朋友,我在下面解释原因。

第三方库的基础实体:

Sylius\UserEntity (TableName: "sylius_user")
============================================
ColA, ColB, ColC

我的班级:

MyProject\UserEntity : Sylius\UserEntity (TableName: "user") <---- overwrite the base table name
========================================
ColD, ColE, ColF

上面的模型代表了最后的方法:我的用户实体扩展了 syslius 的用户实体,应该在表“user”(而不是“user”和“sylius_user”)中持久化和查询,其中包含所有列最终的扩展实体:

表结构:

因此,我的场景中只存在一张表。

Table "user":
=============
ColA, ColB, ColC, ColD, ColE, ColF

前 3 列是基本实体中的属性,后 3 列是“我的”用户实体中的属性,它通过继承获得前三个。

我做了什么:

我的用户类如下所示:

use \Sylius\Component\User\Model\User as BaseUser;

/**
 * User
 *
 * @ORM\Entity(repositoryClass="MyAppName\UserBundle\Repository\UserRepository")
 * @ORM\Table(name="user", uniqueConstraints= ... */
class User extends BaseUser 
{

用户存储库:

class UserRepository extends EntityRepository
{
    /**
     * @param string $usernameOrEmail
     * @return User
     */
    public function findByUsernameOrEmail($usernameOrEmail)
    {
        $qb = $this
            ->createQueryBuilder('u')
            ->where('u.username = :search OR u.email = :search')
            ->setParameter('search', $usernameOrEmail);

        try {
            return $qb->getQuery()->getSingleResult();
        }
        catch(NoResultException $e) {
            return null;
        }
    }
}

此查询会导致从表“user”中选择列,但该查询会尝试两次选择列,每次都使用单独的表别名。结果查询失败,因为它已损坏。

Doctrine 在这里做了什么,看起来像这样:

SELECT s0.ColA, s0.ColB, s0.ColC, 
u0.ColD, u0.ColE, u0.ColF
FROM user u0

大家可以看到,这里使用了一个额外的表别名“s0”,而不是用一个表来引用它。我想要教义做的是:

SELECT u0.ColA, u0.ColB, u0.ColC, 
u0.ColD, u0.ColE, u0.ColF
FROM user u0

如何实现这一点?

对于那些对此任务的目的感兴趣的人:

我们希望将 sylius 包添加到我们长期存在的 symfony 应用程序中,该应用程序已经拥有自己的用户包,其中包含用户模型类和现有数据。

所以我们想通过添加我们自己的属性来扩展 sylius 的用户类,以在 sylius 类和我们的用户类之间建立一个“桥梁”。两者之间的区别在属性方面很小,仅在于重命名和添加一些特殊属性和方法的几列。但是我们有很多从我们的用户类到其他实体的关系,如果我们可以从原则上忽略表继承人员并在这里充当一个简单的类重用事物,这将不是问题。

【问题讨论】:

标签: php mysql symfony doctrine-orm sylius


【解决方案1】:

基类是MappedSuperclass吗?

只要将基类定义为MappedSuperclass,就可以简单地扩展类,将扩展类定义为Entity。

默认情况下,Sylius 将实体定义为 MappedSuperclass。订阅者 (LoadOrmMetadataSubscriber) 传递每个实体并在必要时将 MappedSuperclass 设置为 false,这意味着当在配置中定义类时,它将 MappedSuperclass 更改为实体。

【讨论】:

    猜你喜欢
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 2020-01-30
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    相关资源
    最近更新 更多