Symfony2 和 Doctrine $em->persist VS $em->merge

Symfony2 and Doctrine $em->persist VS $em->merge

你好,我有一个关于 Doctrine 以及 merge()persist()

之间的区别的快速问题

我有一个 NewsBuilder class:

namespace FantasyPro\DataBundle\Builder;

use FantasyPro\DataBundle\Entity\News;
use FantasyPro\DataBundle\Helpers\DateHelper;

class NewsBuilder
{
    /**
     * @var DateHelper $dateHelper
     */
    private $dateHelper;

    public function __construct( DateHelper $dateHelper )
    {
        $this->dateHelper = $dateHelper;
    }

    public function buildNews( $currentNews = null, $news)
    {
        if ( ! $currentNews) { // check if we already have the news stored
            $currentNews = new News();
        }
        $currentNews->setNewsID( $news['NewsID'] );
        $currentNews->setTitle( $news['Title'] );
        $currentNews->setUpdated( $this->dateHelper->parseDate( $news['Updated'] ) );
        $currentNews->setUrl( $news['Url'] );
        $currentNews->setContent( $news['Content'] );
        $currentNews->setSource( $news['Source'] );
        $currentNews->setTermsOfUse( $news['TermsOfUse'] );
        $currentNews->setTeam( $news['Team'] );
        $currentNews->setPlayerID( $news['PlayerID'] );

        return $currentNews;
    }
}

这被NewsPersisterClass

使用

这会使用 FindByOne() 传递我正在解析的数据的 ID 来检查我的存储库。

    namespace FantasyPro\DataBundle\Persisters;

    use Doctrine\ORM\EntityManager;
    use FantasyPro\DataBundle\Builder\NewsBuilder;
    use FantasyPro\DataBundle\Entity\News;

    class NewsPersister {

        /**
         * @var EntityManager $em
         */
        private $em;
        /**
         * @var NewsBuilder $builder
         */
        private $builder;

        public function __construct( EntityManager $em, NewsBuilder $builder )
        {
            $this->em      = $em;
            $this->builder = $builder;
        }

        public function Persist($news){
            //get the news repository
            $repo = $this->em->getRepository( 'DataBundle:News' );

            // get the current news from the db
            $criteria    = array(
                'newsID' => $news['NewsID']
            );

            /**
             * @var News $currentNews
             */
            $currentNews = $repo->FindOneBy( $criteria );

            //todo: use a logger to write this data to file

            //build the news entity
            $currentNews = $this->builder->buildNews( $currentNews, $news );

            //persist the team
            $this->em->persist( $currentNews );
        }
    }

她是我的问题:可以删除 FindByOne() 语句并简单地使用 $em->merge() 而不是 $em->persist()

我认为 $em->merge 将实体设置为根据 ID 是否存在进行更新或插入是正确的吗?不需要我额外调用 he repo 了吗?

不,你不能删除

不同之处在于您之后对实体执行的操作。

Persist 接受一个实体实例,将其添加到持久性上下文并对其进行管理,因此所有其他更新都将由实体管理器管理。

Merge 将创建实体的新实例,从提供的实体复制状态,并将管理新副本,但不会管理传递的实体,因此实体管理器不会缓存进一步的更改

以您为例:如果您将坚持更改为合并,那么它不会有任何区别。所以 merge 将做与 persist 相同的工作。通常,当您分离实体或未序列化(即来自缓存)时,您应该使用合并