创建一个查询以连接symfony2中的两个表

时间:2014-01-10 07:16:31

标签: php symfony symfony-2.1

如何在symfony2中列出两个表连接

我有四张桌子

  1. 国家
  2. CountryTranslation
  3. 国家
  4. StateTranslation
  5. 以下4个表实体

    表(1)国家/地区


    /**
     * 
     *
     * @ORM\Table(name="Country")
     * @ORM\Entity(repositoryClass="Dashboard\CountryBundle\Entity\CountryRepository")
     */
    class Country
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
       /**
         * @ORM\OneToMany(
         *   targetEntity="CountryTranslation",
         *   mappedBy="object",
         *   cascade={"persist", "remove"}
         * )
         */
        private $translations; 
    
    
    }
    

    表(2)CountryTranslation


    /**
     * 
     *
    * @ORM\Table(name="CountryTranslation")
     * @ORM\Entity
     */
    class CountryTranslation
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
      /**
         * @var string $culture
         *
         * @ORM\Column(type="string", length=8)
         */
        private $culture;
    
         /**
         * @ORM\Column(name="country_name", type="string", length=255)
         */
        private $country_name;
    
    
       /**
         * @ORM\ManyToOne(targetEntity="Country", inversedBy="translations")
         * @ORM\JoinColumn(name="country_id", referencedColumnName="id", onDelete="CASCADE")
         */
        protected $object;
    }
    

    表(3)状态


    /**
     *
     * @ORM\Table(name="State")
     * @ORM\Entity(repositoryClass="Dashboard\CountryBundle\Entity\StateRepository")
     */
    class State
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
       /**
         * @ORM\ManyToOne(targetEntity="Country")
         * @ORM\JoinColumn(name="country_id", referencedColumnName="id", onDelete="CASCADE")
         */
        protected $countryId;  
    
    
       /**
         * @ORM\OneToMany(
         *   targetEntity="StateTranslation",
         *   mappedBy="object",
         *   cascade={"persist", "remove"}
         * )
         */
        private $translations;
    
    
    }
    

    表(4)StateTranslation


    /**
     * StateTranslation
     *
     * @ORM\Table(name="StateTranslation")
     * @ORM\Entity
     */
    class StateTranslation
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
    
       /**
         * @var string $culture
         *
         * @ORM\Column(type="string", length=8)
         */
        private $culture;
    
         /**
         * @ORM\Column(name="state_name", type="string", length=255)
         */
        private $state_name;
    
    
       /**
         * @ORM\ManyToOne(targetEntity="State", inversedBy="translations")
         * @ORM\JoinColumn(name="state_id", referencedColumnName="id", onDelete="CASCADE")
         */
        protected $object;
    }
    

    我希望有以下类型列表

    **No  Country name     state name   Action**
     1     India           Gujarat       edit/delete
     2     USA             california    edit/delete    
    

    我在StateRepository文件中有以下代码,但是如何在列表页面上显示国家/地区名称 现在我可以在列表页面中看到吼叫表

    **No  Country name               state name   Action**
     1     3(country id)             Gujarat       edit/delete
     2     5(country id)             california    edit/delete    
    
    public function loadAllState($culture = 'en')
    {
    
        $em = $this->getEntityManager();
        $q  = $em->createQuery("SELECT c, t
                    FROM Dashboard\CountryBundle\Entity\State c
                    LEFT JOIN c.translations t
                    WHERE  t.culture = :culture ")->setParameter('culture', $culture);
        return $q->getResult();
    }
    

    我的另一个问题是

    如何在添加/编辑树枝文件中明智地显示语言

    目前我在StateType.php文件中的代码

    $builder->add('country', 'entity', array(
        'class'         => 'DashboardCountryBundle:Country',
        'property' => 'translations[0].country_name', 
        'query_builder' => function(EntityRepository $er) {
        return $er->createQueryBuilder('mc')
        ->select('mc','d')
        ->innerJoin('mc.translations', 'd')
        ->where('d.culture =  :culture')
        ->setParameter('culture', 'en');
        },
        'label'    => false,
        'attr'=> array('class' => 'validate[required] form-control'),
        'empty_value'=>'Please Select Category'
    ));
    

    它工作正常但是 我的问题是如何减少我在上述声明中使用过的查询?

    目前我正在使用此代码,但面临的问题是我正在获得所有语言的国家 如何语言明智地获得国家

    **StateType.php file**  
          ->add('country', 'entity', array('class' => 'DashboardCountryBundle:CountryTranslation','property' => 'name', 'label' => false,'attr'=> array('class' => 'validate[required] form-control')));
    

1 个答案:

答案 0 :(得分:4)

我认为你几乎就在那里,你只需要与国家实体应用相同的逻辑来获取翻译。

1 在你的State类中改变它是一个好习惯:

protected $countryId;  

到此:

protected $country

为什么?因为它是State实体与Country实体之间的关系(而不是State实体与CountryId字段之间的关系。实体和主键是不同的东西。但是,您使用$countryId实体的主键(Country)来创建与State实体的关系。

注意:因此,您必须将getter和setter更改为getCountry()setCountry($country)

2 这将是您的查询:

public function loadAllState($culture = 'en')
{

    $em = $this->getEntityManager();
    $q  = $em->createQuery("

                SELECT s, st, c, ct
                FROM Dashboard\CountryBundle\Entity\State s

                INNER JOIN s.translations st
                WHERE  st.culture = :state_culture

                INNER JOIN s.country c

                INNER JOIN c.translations ct
                WHERE  ct.culture = :country_culture

        ")
        ->setParameter('state_culture', $culture)
        ->setParameter('country_culture', $culture);

    return $q->getResult();
}

3 您将获得Dashboard\CountryBundle\Entity\State个对象的集合。


额外的乐趣

改为使用查询构建器:

public function loadAllState($culture = 'en')
{
    //   we create a query builder
    $queryBuilder = $this->getEntityManager()
        ->createQueryBuilder();

    //   we select what we need
    $queryBuilder
        ->select('s, st, c, ct')

    //  from the appropriate connection class
        ->from('Dashboard\CountryBundle\Entity\State', 's')

    //  join the state translations
        ->innerJoin('s.translations','st')
        ->andWhere('st.culture = :state_culture')
        ->setParameter('state_culture', $culture)

    //  join the country 
        ->innerJoin('s.country','c')

    //  join the country translations
        ->innerJoin('c.translations','ct')
        ->andWhere('ct.culture = :country_culture')
        ->setParameter('country_culture', $culture);

    return $queryBuilder
        ->getQuery()
        ->getResult();
}