使用后师获取自动化ID以获取其他字段



我有一个带有自动核ID的产品,并且还具有一个productCode字段,该产品基于用户选择与自动型钥匙相结合以制造productcode。但是,在插入新产品时,我无法抓住自动基因ID。

我使用了第一学者&预熟书,但在插入新产品时不会抓住ID。只有在更新时才能抓住ID

/**
 * @ORMPrePersist
 * @ORMPreUpdate
 */
public function setProductcode() 
{

  $option1 = $this->option1;   
  $option2 = $this->option2; 
  $id = $this->id;
  $whole = $option1.''.$option2.''.$id;    
  $this->productcode = $whole;

}

我尝试使用后世,并将我的字段更改为nulablae true,但它将productcode保存为null。

/**
 * @var string
 *
 * @ORMColumn(type="string", length=191, unique=true, nullable=true)
 */
private $productcode;

我一起使用了后载并将其延伸在一起,它确实将prodesscode显示为输出。但是它并不能保存DB。

 * @ORMPostLoad
 * @ORMPostPersist

如何在实体中获取ID将其放在其他字段中?预先感谢!


编辑

我制作了一个EasyAdminsubcriber,当我使用Pre_persist返回时,它起作用。但是,下面的代码已更新为post_persist。但是我很难与LifeCycleVentargs一起实施冲洗功能。

我收到以下错误

Argument 2 passed to AppEventSubscriberEasyAdminSubscriber::setProductcode() must be an instance of DoctrineCommonPersistenceEventLifecycleEventArgs, string given, called in 

以下是我的post_persist代码

<?php 
# src/EventSubscriber/EasyAdminSubscriber.php
namespace AppEventSubscriber;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
use SymfonyComponentEventDispatcherGenericEvent;
use AppEntityProduct;
use DoctrineCommonPersistenceEventLifecycleEventArgs;
class EasyAdminSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents()
    {
        return array(
            'easy_admin.post_persist' => array('setProductcode'),
        );
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function setProductcode(GenericEvent $event, LifecycleEventArgs $args)
    {
      $entityManager = $args->getEntityManager();

        $entity = $event->getSubject();

        if (!($entity instanceof Product)) {
            return;
        }

        $whole = 'yooo'; 

        $entityManager->flush();
        $entity->setProductcode($whole);
        $event['entity'] = $entity;
    }
}

默认情况下,仅设置ID,当实体被冲洗到数据库时。这意味着,在冲洗实体然后再次冲洗后,您必须生成产品代码。学说不能使用一些精美的魔法来确定ID,然后才能真正从数据库中回到回音之前,因此没有其他方式。(如果您想做所有这些实体,我无法想象另一种实用和干净的方法(

update

您应该使用后世(同时保留预倍(。

在实体持续存在之后,实体发生后期事件。它将在数据库插入操作之后调用。生成的主要钥匙值可在后代事件中可用。(来源(

因此,生成的主键在那里可用。但是,这只是您冲洗实体之后。因此,您还必须再次冲洗也将producterder写入数据库。

创建适当的事件处理程序(因为" setProductCode"是一个设定器,而不是事件处理程序,至少是名称的(

/**
 * PostPersist triggers after the _creation_ of entities in db
 * @ORMPostPersist
 */
public function postPersist(LifecycleEventArgs $args) {
    $this->setProductcode();
    // need to flush, so that changes are written to database
    $args->getObjectManager()->flush();
}   
/**
 * PreUpdate triggers before changes are written to db
 * @ORMPreUpdate
 */
public function preUpdate() {
    $this->setProductcode(); 
    // don't need to flush, this happens before the database calls
}

(请参阅https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/reference/events.html#lifecycle-callbacks-event-event-argument,以获取更多信息(

(免责声明:此答案自首次创建以来已进行了大量编辑,将连接的评论部分留而没有相关参考(

如果只是其他列的串联,您真的需要持久持续效果吗?只使用有效的getter呢?

public function getProductcode() 
{
  if(!empty($this->productcode)){
    return $this->productcode;
  }
  if(empty($this->id)){
    return "to be determined";
  }
  $this->productcode = $this->option1 . $this->option2 . $this->id;
  return $this->productcode;
}

好的,所以我现在有2个解决方案可以在另一个字段(不使用控制器(设置自动化ID。第一个直接在实体文件本身中,如@Jakumi答案所示。

   public function setProductcode()
    {
      $part = $this->producttype->gettypenumber();
      $id1 = $this->id;
      $part = sprintf("%03d", $id1);
      $whole = $part1.''.$part2;    
      return $this->productcode= $whole;
    }

/**
 * PostPersist triggers after the _creation_ of entities in db
 * @ORMPostPersist
 */
public function postPersist(LifecycleEventArgs $args) {

    $this->setPoductcode();
    // need to flush, so that changes are written to database
    $args->getObjectManager()->flush();
}   
/**
 * PreUpdate triggers before changes are written to db
 * @ORMPreUpdate
 */
public function preUpdate() {

    $this->setProductcode();
    // don't need to flush, this happens before the database calls
}

另一种解决方案是使用Eventsubscriber。

<?php 
# src/EventSubscriber/EasyAdminSubscriber.php
namespace AppEventSubscriber;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
use SymfonyComponentEventDispatcherGenericEvent;
use DoctrineORMEntityManagerInterface;
use AppEntityProduct;
use DoctrineCommonPersistenceEventLifecycleEventArgs;
class EasyAdminSubscriber implements EventSubscriberInterface
{


    public function __construct(EntityManagerInterface $em) {
        $this->em = $em;
    }

    public static function getSubscribedEvents()
    {
        return array(
            'easy_admin.post_persist' => array('setProductcode'),
        );
    }

    public function setProductcode(GenericEvent $event)
    {

        $entity = $event->getSubject();
        if (!($entity instanceof Product)) {
            return;
        }

        $this->em->flush();
        $entity->setProductcode();
        $this->em->flush();
    }
}

和我的实体代码,带有pstpersist&amp;preupdate

/**
 * @ORMPostPersist
 * @ORMPreUpdate
 */
public function setProductcode() 
{

    $part1 = $entity->getProducttype()->getTypenumber();
    $id1 = $entity->getId();
    $part2 = sprintf("%03d", $id1);
    $whole = $part1.$part2; 
  $this->productcode = $whole;

}

感谢@Jakumi的解释&amp;两种解决方案的指南。

最新更新