【问题标题】:Symfony2: custom entity?Symfony2:自定义实体?
【发布时间】:2013-04-18 20:25:46
【问题描述】:

解决this question 中提出的问题的解决方案,其中客户端实体被拆分为两个数据库 - 一个本地,一个外部,是构建本地客户端,使其包含作为对象的外部客户端并具有 getter/setter维护外部客户端对象。本地关系在本地 Client 实体中维护。现在的问题是如何最好地创建客户端实体,以便它可以在多个地方使用。

当前客户端控制器方法

public function getClient($id = null) {
    if (!empty($id)) {
        $localEm = $this->getDoctrine()->getManager();
        $foreignEm = $this->getDoctrine()->getManager('split');

        $client = $localEm->getRepository('ManaClientBundle:Client')->find($id);
        $foreignId = $client->getCid();
        $foreignClient = $foreignEm->getRepository('ManaSplitBundle:Client')->find($foreignId);

        $client->setForeignClient($foreignClient);
    } else {
        $client = new Client();
        $client->setForeignClient(new ForeignClient());
    }
    return $client;
}

尝试在客户端存储库中执行此操作或类似操作失败。正如尝试将以下服务注入独立类一样。这将失败,并出现有关缺少构造函数的参数 1 的错误。

services.yml sn-p:

      foreign_client:
        class: Mana\ClientBundle\DataCombine\ClientCombine
        arguments:
          localEm: @doctrine.orm.entity_manager
          foreignEm: @doctrine.orm.split_entity_manager

ClientCombine 类 sn-p:

namespace Mana\ClientBundle\DataCombine;

use Doctrine\ORM\EntityManager;

class ClientCombine {

    private $localEm;
    private $foreignEm;

    public function __construct(EntityManager $localEm, EntityManager $foreignEm) {
        $this->localEm = $localEm;
        $this->foreignEm = $foreignEm;
    }
...
}

【问题讨论】:

  • “在多个地方使用”是什么意思?
  • @Lighthart:需要访问客户端实体的控制器不止一个。例如,客户端联系人通过 ContactController 进行管理。你的问题让我怀疑我是否过度设计了这个东西。
  • 您已经对此进行了一段时间的研究,我正在尝试了解它与您的其他问题的关系......但实体就是实体。所有控制器都可以访问它,前提是所有控制器都可以访问所有存储库(这将是“正常的”......)
  • 如果我可以在存储库中构建这个混合客户端,所有控制器都可以访问。据我所知,不可能将参数传递给将构建实体的自定义存储库函数。如果可能的话,我真的很想看到。在实体内部使用实体管理器似乎是不合适的;这样做可以解决问题

标签: php symfony doctrine


【解决方案1】:

我使用两个实体 Beverage 和 Beer。每个都有自己的实体管理器。啤酒是 在冷淡和饮料在冰箱里。我的策略是获取两种类型的列表 实体,并将它们配对,在饮料方面,并匹配它们。相似的 功能存在于单个实体中。但是,如果您处理的列表 您需要批量处理实体,否则您将有一个额外的查询FOR EACH 列表中的实体。这很糟糕。

以下已,我相信所有非必要的部分都被剥离了。这是一个 痛苦和麻烦的方法。我能够通过去一个放弃它 基于模式的方法,因为您可以在学说形式中指定模式。 但是,这段代码确实为我完成了这项工作。

你已经被反复警告过,(实际上是在其他问答对中被我警告过。)

一个超级控制器,你的控制器应该扩展它以获得婚姻 功能。

    <?php

    namespace beverage\beverageBundle\Controller;

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;

    class ThawController extends Controller
    {
        public static function defrost( $controller, $beverages ) {
            $em = $controller->getDoctrine()->getManager( 'frosty' );
            $beverageIds = array();
            foreach ( $beverages as $k =>$v ) {
                array_push( $beverageIds, $v->getIceid() );
            }

            $qb=$em->getRepository( 'frostyfrostyBundle:Beer' )
            ->createQueryBuilder( 't' )
            ;
            if ( array() == $beverageIds ) {return null;}
            $qbeers=$qb->where( $qb->expr()
                ->in( 't.id', $beverageIds ) )
            ->getQuery()
            ->getResult();
            foreach ( $qbeers as $k => $beer ) {
                $id=$beer->getId();
                $beers[$id]=$beer;
            }
            foreach ( $beers as $k => $beer ) {
            }
            foreach ( $beverages as $k => $beverage ) {
                $beverage->ice( $beers[$beverage->getIceid()] );
            }

            return $beverages;
        }

        public static function thaw( $controller, $beverage ) {
            $beer= null;
            $em = $controller->getDoctrine()->getManager( 'frosty' );
            $beer=$em->getRepository( 'frostyfrostyBundle:Beer' )
            ->createQueryBuilder( 't' )
            ->where( 't.id = '.$beverage->getIceid() )
            ->getQuery()
            ->getSingleResult();
            $beverage->ice( $beer );
            return $beverage;
        }
    }

和实体代码:

    <?php

    namespace freezer\freezerBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;
    use frosty\frostyBundle\Entity\Beer as beer;

    class Student {
        private $id;
        private $iceid;

        public function getId() {
            return $this->id;
        }

        public function setIceid( $iceid ) {
            $this->iceid = $iceid;

            return $this;
        }

        public function getIceid() {
            return $this->iceid;
        }

        public function __construct( beer $beer=null
                                   , $manyToMany = null ) {
            if ( $beer instanceof \frosty\frostyBundle\Entity\Beer ) {
                $this->ice( $beer, $manyToMany );
            }
        }

        public function setBeer( \frosty\frostyBundle\Entity\Beer $beer=null){
            $this->beer = $beer;

            return $this;
        }

        public function getBeer() {
            return $this->beer;
        }

        public function ice( snowflake $snowflake=null
                           , $manyToMany = null ) {
            if ( $snowflake instanceof 
                 \frosty\frostyBundle\Entity\Beer ) {
                $methods=get_class_methods( get_class( $snowflake ) );
                $methods=array_filter( $methods
                                     , function( $item ) use ( &$methods ) {
                                           next( $methods );
                                           if ( "__" == substr($item 0,2)) 
                                               return false;
                                           if ( "remove" == substr($item,0,6))
                                               return false;
                                           if ( "get" == substr($item,0,3)) 
                                               return false; 
                                           return true;
                                        } );

                $amethods=array_filter( $methods
                                      , function( $item ) use ( &$methods ) {
                                            next( $methods );
                                            if ( "set" == substr($item,0,3)) 
                                                return false;
                                            return true;
                                       } );

                $methods=array_filter( $methods
                                     , function( $item ) use ( &$methods ) {
                                           next( $methods );
                                           if ( "add" == substr($item,0,3)) 
                                               return false;
                                           return true;
                                       } );

                foreach ( $methods as $k => $v ) {
                    $this->{$v}( $snowflake->{str_replace( "set"
                                                         , "get"
                                                         , $v )}() );
                }

                foreach ( $amethods as $k => $v ) {
                    if ( $manyToMany ) {
                        $results=$snowflake->{str_replace( "add"
                                                         , "get"
                                                         , $v )}();
                        foreach ( $results as $key =>$value ) {
                            $this->{$v}( $value );
                        }
                    }
                }
                $this->setIceid( $beer>getId() );
            }
        }

    }

【讨论】:

  • 我对自己的厚度感到震惊。虽然我现在当然可以使用冷的,而且你的代码让我流口水,但答案要容易得多。我只需要ContactController extends ClientController!而且由于外部和本地客户端数据之间存在一对一的关系,因此无需在查询或数组操作方面做太多事情。 +1 '因为我现在想要一个冷冰冰的!
  • 您可以这样做,但是对于大型实体列表,您仍然会遇到查询过多的问题。享受一个冷的。
猜你喜欢
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多