9

我在使用组序列化具有许多关系的实体时遇到问题。我在以这种方式序列化相关实体时遇到问题。

假设我有两个实体:产品和相关元素。

/**
 *
 * @Serializer\ExclusionPolicy("none")
 */
class Product {

    /**
     * Primary key
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * 
     * @Serializer\Groups({"list","details"})
     * @Serializer\Type("integer")
     */
    protected $id;

    /**
     * @Serializer\Groups({"list","details"})
     * @Serializer\Type("string")
     */
    protected $name;

    /**
     * @ORM\Column(name="description", type="string", length=4096, nullable=true)
     * 
     * @Serializer\Groups({"details"})
     * @Serializer\Type("string")
     */
    protected $description;

    /**
     * @var ArrayCollection
     * 
     * @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectResource", mappedBy="project")
     * @Serializer\Groups({"details"})
     * @Serializer\Type("ArrayCollection<Element>")
     */
    protected $details1;

    /**
     * Relation to project tasks
     * @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectTask", mappedBy="project")
     * @Serializer\Exclude()
     * @Serializer\Type("ArrayCollection<Element>")
     */
    protected $details2;

    ...

}

元素实体具有类似的结构:

/**
 *
 * @Serializer\ExclusionPolicy("none")
 */
class Element {

    /**
     * Primary key
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * 
     * @Serializer\Groups({"list","details"})
     * @Serializer\Type("integer")
     */
    protected $id;

    /**
     * @Serializer\Groups({"list","details"})
     * @Serializer\Type("string")
     */
    protected $name;

    /**
     * @ORM\Column(name="description", type="string", length=4096, nullable=true)
     * 
     * @Serializer\Groups({"details"})
     * @Serializer\Type("string")
     */
    protected $description;

    ...
}

我的问题是,当我使用“详细信息”组实体序列化产品时,我只想序列化元素的 id,但正如您所见,实体已定义与产品相同的组(以防我需要元素对象的详细信息),因为我想要在我的所有实体上都有统一的组,并防止创建数百个组,如“product_details”、“element_details”等。

当我访问关系或类似的东西时,有没有办法最终更改序列化组?处理程序可能或类似的东西?

问候和感谢任何帮助

4

3 回答 3

7

不幸的是,你不能真的(但继续阅读;-)),至少在不更改序列化程序库的情况下不能。罪魁祸首是组列表在您开始序列化过程的那一刻固定在 a GroupExclusionStrategy(由 引用)内。Context一旦(反)序列化运行时,代码中实际上有一个断言可以防止修改排除策略。

但碰巧的是,我在我的一个项目中也遇到了完全相同的问题,我对序列化程序代码进行了必要的更改。我已经清理了一些代码并将其上传到 Github(https://github.com/andreasferber/serializer/tree/recursion-groups)。

它添加了新的属性元数据,您可以在下降到子对象时添加、删除或覆盖组。使用注释它看起来像这样:

/**
 * @Serializer\RecursionGroups(set={"foo", "bar"}, add={"baz"}, remove={"Default"})
 */
private $myProperty;

您也应该能够使用 XML 或 Yaml 元数据,但是这是未经测试的,因为我不使用它们并且我还没有添加测试用例。查看参考文档。由于我还没有进行任何优化,如果您的实体真的很大并且嵌套很深,它可能会对性能产生显着影响。

如果您觉得这很有用,或者您有任何建议,请告诉我,因为如果这不仅是我需要的,我将添加一些测试并尝试将其提交到上游。

于 2013-10-15T13:26:48.320 回答
2

官方文档中实际上描述了一个解决方案。

话虽这么说,@aferber 提出的解决方案在很多方面似乎更好:更容易维护,更少冗长,更灵活......

于 2017-07-17T14:04:49.913 回答
0

你需要使用setGroups.

_group不需要官方文档中使用的后缀。

$context->setGroups([
    'Default', //if you want

    // use this linked entity but show only its id
    'group_of_linked_field',
    'group_of_linked_field' => [
        'id' // you will need to define this group first
    ],

    // use this linked entity and show fields as described
    'group_of_other_linked_field',
    'group_of_other_linked_field' => [
        // just as an example
        'Default',
        'details',
    ],
]);

不适用于addGroupor addGroups!他们都不会接受关联数组。setGroups是您的(唯一?)解决方案。

于 2020-06-11T10:39:38.477 回答