【问题标题】:Create a query to join two tables in symfony2创建一个查询以连接 symfony2 中的两个表
【发布时间】:2014-01-29 01:39:24
【问题描述】:

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

我有四张桌子

  1. 国家
  2. 国家/地区翻译
  3. 状态
  4. 状态转换

以下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')));

【问题讨论】:

  • 那么@shivam 效果好吗?你曾经使用过 QueryBuilder 吗?如果您愿意,可以更轻松地进行查询,我可以使用 QueryBuilder 版本更新我的答案。告诉我!
  • 嘿@shivam,我用 QueryBuilder 方法更新了我的答案,以便您可以使用它,看看创建查询是多么容易。继续玩吧!

标签: php symfony symfony-2.1


【解决方案1】:

我想你快到了,你只需要对国家实体应用相同的逻辑来获取翻译。

1 在 State 类中更改它是一个很好的做法:

protected $countryId;  

到这里:

protected $country

为什么?因为这是State实体和Country实体之间的关系(而不是State实体和CountryId字段之间的关系。实体和主键是不同的东西。但是,您使用 Country 实体的主键 ($countryId) 来创建与 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();
}

【讨论】:

    猜你喜欢
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 2016-05-27
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多