如何解决“多对一”关系中重复的条目?

时间:2019-05-21 08:34:24

标签: php symfony doctrine-orm doctrine

在我们的一种产品中,我们目前遇到一些有关多对一关系的问题。情况如下:

  • 我们有一个“ Like”聚合,其中包含用户ID,“ LikeType”实体和LikedEntityID。
  • LikeType实体由一个ID和一个字符串值组成,目前为eather“ article”或“ media”,但以后可以扩展。
  • LikedEntityId表示已被喜欢的实体本身的ID(因此,文章ID或媒体ID)

当前设置的问题是,当我们插入新的点赞时,每个单独的点赞都会得到一个具有与其他相同的字符串值的新的点赞类型,而我希望它们具有相同的ID。

更直观,这是显示我们喜欢的当前表。它有一个like_type_id,其中包含对相似类型的引用。

The table with likes

这是我们用于类似类型的表格。如您所见,它会生成2个具有不同ID的不同LikeType,并将它们链接到like。

The table with liketypes

我的首选情况是,只要我坚持一个新的like,Doctrine就会检查liketype是否已经存在,如果存在,则将已经存在的liketype id链接到like。因此,只有1个“媒体”喜欢类型,并且两个喜欢具有相同的like_type_id。

这是我的Like ORM实体的xml配置:

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="MyNamespace\Like\Domain\Entity\Like" table="likes" repository-class="MyNamespace\Like\Infrastructure\Repository\LikeRepository">
        <id name="id" type="integer" column="id" length="191">
            <generator strategy="AUTO" />
        </id>

        <field name="userId" type="string" length="191" />

        <many-to-one field="likeType" target-entity="MyNameSpace\Like\Domain\Entity\LikeType" fetch="EAGER">
            <cascade>
                <cascade-persist/>
                <cascade-merge/>
            </cascade>
        </many-to-one>

        <field name="likedObjectId" type="string" length="191" />

    </entity>
</doctrine-mapping>

这是类似类型的xml配置:

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="MyNameSpace\Like\Domain\Entity\LikeType" repository-class="MyNameSpace\Like\Infrastructure\Repository\LikeRepository">
        <id name="id" type="string" length="191">
            <generator strategy="AUTO" />
        </id>

        <field name="type" type="string" length="191" />
    </entity>
</doctrine-mapping>

也许我们犯了一个简单的错误,但是我找不到解决该问题的方法,尽管我们已经看到了一些解决方法,方法是检查数据库中是否存在现有的liketype,然后在持久化之前插入ID,但我们认为ORM的任务就是为我们做到这一点。因此,我想知道我们是否为了实现此目的而犯了一些配置错误。

谢谢。

-丹尼·埃伦斯

1 个答案:

答案 0 :(得分:1)

使like_type.type字段唯一,这将防止插入重复的值:

<field name="type" type="string" length="191" unique="true" />

然后,当您要插入新的like时,可以检查类型是否已经存在:

// This is the name of the like_type --------------------------------------------------------------------v-----------v
if (($LikeType = $entityManager->getRepository('MyNameSpace\Like\Domain\Entity\LikeType')->findOneByName($likeTypeName)) == null)
{
    // the Like type wasn't found, create a new one
    $LikeType = new LikeType();
    $LikeType->setType($likeTypeName);
    $entityManager->persist($LikeType);
}
// Whatever if the like type is a new one or not, it can now be set to the like
$Like->SetLikeType($LikeType);
$entityManager->persist($Like);