Извлечение исключения связанных объектов при работе с базой данных mutil - PullRequest
0 голосов
/ 01 января 2019

Когда я использую базу данных mutil с доктриной для связанных объектов, она не может найти таблицу правильным способом.ta - имя таблицы в базе данных acc.tb также является именем таблицы в торговой базе данных.та запись: имя идентификатора 1 та 名称

тб запись: имя идентификатора 1 тб 名称

        $em=$this->getDoctrine()->getRepository(ta::class,'customer');
        $ta=$em->find(2);//now ,it can fetch the data,and the data is right
        $tb=$ta->getTbTable();
        $szName=$tb->getName(); //i want to get the tb record,it will throw an exception :

................................... 'acc.tb' не существует "

на самом деле, tb находится в торговой базе данных.

как исправитьэти проблемы

<?php
    namespace AppBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\ORM\Mapping\PrePersist;
    use Doctrine\ORM\Mapping\PreUpdate;
    use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
    use Symfony\Component\Validator\Constraints as Assert;

    /**
     * @ORM\Table(name="ta")
     * @ORM\Entity(repositoryClass = "AppBundle\Entity\taRepository")
     * @ORM\HasLifecycleCallbacks()
     * @package AppBundle\Entity
     */
    class ta {
        /**
         * @ORM\Column(type="integer",unique=true)
         * @Assert\NotBlank(message="账号ID不能为空")
         * @ORM\Id
         */
        private $id;
        /**
         * @ORM\Column(type="string")
         */
        private $name;

        /**
         * @ORM\ManyToOne(targetEntity="AppBundle\EntityTrade\tb")
         * @ORM\JoinColumn(name="id",referencedColumnName="id")
         */
        private $tb_table;

    /**
     * Set id.
     *
     * @param int $id
     *
     * @return ta
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name.
     *
     * @param string $name
     *
     * @return ta
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set tbTable.
     *
     * @param \AppBundle\EntityTrade\tb|null $tbTable
     *
     * @return ta
     */
    public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
    {
        $this->tb_table = $tbTable;

        return $this;
    }

    /**
     * Get tbTable.
     *
     * @return \AppBundle\EntityTrade\tb|null
     */
    public function getTbTable()
    {
        return $this->tb_table;
    }
}

<?php
    namespace AppBundle\EntityTrade;
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\ORM\Mapping\PrePersist;
    use Doctrine\ORM\Mapping\PreUpdate;
    use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
    use Symfony\Component\Validator\Constraints as Assert;

    /**
     * @ORM\Table(name="tb")
     * @ORM\Entity(repositoryClass = "AppBundle\EntityTrade\tbRepository")
     * @ORM\HasLifecycleCallbacks()
     * @package AppBundle\EntityTrade
     */
    class tb {
        /**
         * @ORM\Column(type="integer",unique=true)
         * @Assert\NotBlank(message="账号ID不能为空")
         * @ORM\Id
         */
        private $id;
        /**
         * @ORM\Column(type="string")
         */
        private $name;

    /**
     * Set id.
     *
     * @param int $id
     *
     * @return tb
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name.
     *
     * @param string $name
     *
     * @return tb
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
}

class defaultController{
  public function indexAction(){
             $em=$this->getDoctrine()->getRepository(ta::class,'customer');
            $ta=$em->find(2);
            $tb=$ta->getTbTable();
            $szName=$tb->getName();
 }
}

1 Ответ

0 голосов
/ 02 января 2019

Это не будет работать таким образом.EntityManager Doctrine поддерживает только управление объектами в пределах одной базы данных, поэтому ваше отношение между базами данных между ta и tb не будет установлено.Пожалуйста, обратитесь к этой проблеме в Doctrine bug tracker для получения дополнительной информации.

Однако ваша цель может быть достигнута несколько иным способом.Вы не можете установить связи между базами данных между сущностями, но вы, конечно, можете хранить идентификаторы, которые ссылаются на сущности в разные базы данных.Следовательно, вы можете переместить всю логику связей между базами данных в репозитории.Например, предположим, что у вас есть 2 EntityManager для каждой базы данных: $accEm для acc базы данных и $tradeEm для trade базы данных.Принимая во внимание, что вы используете Symfony - их можно настроить в конфигурации DoctrineBundle, а затем внедрить в службы.

Вам потребуется внести некоторые изменения в код:

ta.php , я опустил большую часть кода, чтобы выразить изменения, которые необходимо внести.

namespace AppBundle\Entity;

class ta
{
    /**
     * @ORM\Column(type="integer", nullable=true)
     * @var int
     */
    private $tb_table;  // Notice that it is not a reference anymore, but simple integer

    /**
     * Set tbTable.
     *
     * @param \AppBundle\EntityTrade\tb|null $tbTable
     *
     * @return ta
     */
    public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
    {
        // You can also consider updating this method to accept plain integers aswel
        $this->tb_table = $tbTable instanceof \AppBundle\EntityTrade\tb ? $tbTable->getId() : null;
        return $this;
    }

    /**
     * Get tbTable.
     *
     * @return int|null
     */
    public function getTbTable()
    {
        // Also notice that plain integer is returned, you may want to rename column and method names to reflect this change of column meaning
        return $this->tb_table;
    }
}

taRepository.php , я также опустил большую частькод, который может быть там

namespace AppBundle\Entity;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

class taRepository extends EntityRepository {
    /**
     * @var EntityManager
     */
    private $tradeEm;

    /**
     * @param EntityManager $tradeEm
     */
    public function setTradeEntityManader(EntityManager $tradeEm)
    {
        // It is required to pass instance of EntityManager for "trade" database here. It should be done via Symfony services configuration, please refer Symfony documentation on this topic if needed
        $this->tradeEm = $tradeEm;
    }

    /**
     * @param ta $ta
     * @return \AppBundle\EntityTrade\tb|null
     */
    public function getTbTable(ta $ta) {
        // This method should be used instead of $ta::getTbTable()
        $tbId = $ta->getTbTable();
        if ($tbId === null) {
            return null;
        }
        return $this->tradeEm->find(\AppBundle\EntityTrade\tb::class, $tbId);
    }
}

defaultController.php

namespace AppBundle\Controller;

use Doctrine\ORM\EntityManager;

class defaultController
{
    /**
     * @var EntityManager
     */
    private $tradeEm;

    /**
     * @param EntityManager $tradeEm
     */
    public function __construct(EntityManager $tradeEm)
    {
        // Same as before, this should be instance of EntityManager for "trade" database
        $this->tradeEm = $tradeEm;
    }


    public function indexAction()
    {
        $em = $this->getDoctrine()->getRepository(ta::class, 'customer');
        $ta = $em->find(2);
        // Notice that we're not receiving "trade" database entity directly, but using corresponding EntityManager instead
        $tb = $this->tradeEm->getTbTable($ta);
        if ($tb !== null) {
            $szName = $tb->getName();
        }
    }
}
...