Symfony 我可以用Alice装置覆盖自动增量ID吗?

Symfony 我可以用Alice装置覆盖自动增量ID吗?,symfony,doctrine-orm,nelmio-alice,alice-fixtures,Symfony,Doctrine Orm,Nelmio Alice,Alice Fixtures,我将Symfony2与条令一起使用,并使用Alice Fixture包生成用于测试的装置 在一种情况下,我需要为特定测试创建一个id为148的夹具。我们所有的ID都配置为自动递增,所以我目前正在创建147个虚拟记录,只是为了创建我需要的记录 我希望使用此定义强制将id设置为148: invoiceClassNoClass (extends invoiceClass): id: 148 sortOrder: 1 label: 'No Class' 不幸的是,这不起作用。

我将Symfony2与条令一起使用,并使用Alice Fixture包生成用于测试的装置

在一种情况下,我需要为特定测试创建一个id为148的夹具。我们所有的ID都配置为自动递增,所以我目前正在创建147个虚拟记录,只是为了创建我需要的记录

我希望使用此定义强制将id设置为148:

 invoiceClassNoClass (extends invoiceClass):
    id: 148
    sortOrder: 1
    label: 'No Class'
不幸的是,这不起作用。在谷歌搜索中,我读到一条简短的评论,指出我首先需要向我的实体添加一个setId方法。我试过了,但没什么不同。实际上,如果不需要,我不想添加assetid方法,因为它违反了我们的完整性规则,我们从不允许设置id


也许可以使用反射类?也许这是Alice内置的,我对此一无所知?

如果您希望条令为自动增量Id保存某个值,那么您必须停用条令元数据中的自动增量。看

更新: 在对该主题进行进一步研究之后,我意识到在fixture中硬编码id有其自身的问题,通常不是一个好主意。相反,当您需要检查特定记录时,最好通过yml文件中的引用获取装置


由于问题是关于Alice fixtures捆绑包的,我发现以下内容对我有用:

protected $idGeneratorTypes = [];

protected function allowFixedIdsFor(array $entityClasses)
{
    $em = $this->getContainer()->get('doctrine')->getManager();
    foreach ($entityClasses as $entityClass) {
        $metadata = $em->getClassMetadata($entityClass);
        $this->idGeneratorTypes[$entityClass] = $metadata->generatorType;
        $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
    }
}

protected function recoverIdGenerators()
{
    $em = $this->getContainer()->get('doctrine')->getManager();
    foreach ($this->idGeneratorTypes as $entityClass => $idGeneratorType) {
        $metadata = $em->getClassMetadata($entityClass);
        $metadata->setIdGeneratorType($idGeneratorType);
    }
}
然后在测试的setUp()方法中

    $this->allowFixedIdsFor([
        MyEntity::class,
    ]);


    $this->loadFixtureFiles([
        './tests/DataFixtures/ORM/my_entities.yml',
    ]);

    $this->recoverIdGenerators();

看起来您的实体中不需要有setId()方法。

我也遇到了这个问题,因为我希望某些ID在每次运行时都相同,因为我想在调试应用程序中使用
UUID
策略引用它们

我所做的:

1) 编写了一个命令来包装
hautelook:fixtures:load

protected function execute(InputInterface $input, OutputInterface $output)
{
    $container     = $this->getContainer();
    $entityManager = $container->get('doctrine.orm.default_entity_manager');

    $metadata = $entityManager->getClassMetaData(App::class);
    $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
    $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());

    $application = new Application($kernel);
    $application->setAutoExit(false);

    $this->loadFixtures($application, $output);
}
对所有想要拥有自定义ID的类(
App::class
)执行
$metadata
-stuff

2) 我创建了一个模板来生成
id
,就像条令一样

id (template):
    id (unique):   '<uuid()>'
4) 如果我不想使用自定义id,我只是不覆盖
id
字段:

app_another (extends id):
    title: 'Just another app with an id I do not care about'
证明:


我首先需要向实体添加一个setId方法。我试过了,但没什么不同。请更准确地解释一下,你有没有出错?添加
setId
可能是解决您的问题的最佳且简单的方法。ID生成器类型将覆盖您使用setId设置的内容,因此仅在对象上设置它不会起作用。@David确定吗?IIRC,仅当主id为空时才使用自动递增。@A.L-您可能是对的,但从其他阅读中,我得到的印象不是那么简单。@A.L我没有收到错误,只是没有设置id。正如David所说,id生成器具有优先级。换句话说,我们是否可以说,调用
setId()
函数必须使用此代码?不,您也可以在不使用该代码的情况下调用setId,但doctrine将忽略您的id值,并且仍然使用自动增量值。谢谢,这是我的想法,我的句子表达得很糟糕。我可以补充一下,您可以调用
公共函数setId(){$this->id=$id;}
,并且
id
的值不会被覆盖。在你回答的最后?我认为最好明确地说出来。这并不能真正回答关于爱丽丝的问题。你的回答太笼统了。
id (template):
    id (unique):   '<uuid()>'
app_custom (extends id):
    id:    'whatever-i-want'
    title: 'My custom entity'
app_another (extends id):
    title: 'Just another app with an id I do not care about'