简体   繁体   English

具有ManyToMany关系的Doctrine2中此SQL语句的DQL

[英]DQL for this SQL statement in Doctrine2 with ManyToMany relationship

I've made this SQL query to get the data I need from DB and it works exactly as I want: 我进行了此SQL查询,以便从数据库中获取所需的数据,并且它完全可以按我的意愿运行:

SELECT DISTINCT ofreg.nombre as oficina 
  FROM nomencladores.oficina_regional AS ofreg  
  LEFT JOIN negocio.solicitud_usuario_oficina_regional AS solusofreg
    ON (ofreg.id = solusofreg.oficina_regional_id)
  JOIN nomencladores.tipo_tramite tram
    ON (tram.id = solusofreg.tipo_tramite_id)
  WHERE (tram.id = 1);

Since my relation will not generates any extra field on the third table then I decide to go for proper annotations on my entities, take a look: 由于我的关系不会在第三个表上生成任何额外的字段,因此我决定在我的实体上使用适当的注释,请看一下:

class TipoTramite
{
    use IdentifierAutogeneratedEntityTrait;
    use NamedEntityTrait;
    use ActiveEntityTrait;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\OficinaRegional", inversedBy="tipoTramites", cascade={"persist"})
     * @ORM\JoinTable(name="negocio.solicitud_usuario_oficina_regional", schema="negocio",
     *      joinColumns={@ORM\JoinColumn(name="oficina_regional_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="tipo_tramite_id", referencedColumnName="id")}
     * )
     */
    protected $oficinaRegionals;
}

class OficinaRegional
{
    use IdentifierAutogeneratedEntityTrait;
    use NamedEntityTrait;
    use ActiveEntityTrait;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\TipoTramite", mappedBy="oficinaRegionals", cascade={"persist"})
     */
    protected $tipoTramites;
}

Having those entities and supposing they are right (correct me if I'm wrong) I need to write a DQL that satisfies the above SQL code, can any give me some help writing this DQL? 拥有这些实体并假设它们是正确的(如果我错了,请纠正我)我需要编写一个满足上述SQL代码的DQL,有什么可以帮助我编写此DQL的吗?

I always have do it having a intermediary entity but this case is totally new for me. 我总是有一个中介实体来做的,但是这种情况对我来说是全新的。 As and addition I know a workaround on this and will be create a view at DB level and write a entity just for that view with not set method just the get methods since will be a read only entity but I don't know if is the right path to go and I really like to learn how to do it using ManyToMany (in my project I have a lot of relation of this type so for sure I'll need this help later in the near future). 另外,我知道一种解决方法,它将在数据库级别创建一个view ,并为该视图编写一个实体,而不使用set方法,而只是使用get方法,因为它将是一个只读实体,但是我不知道正确的道路,我真的很想学习使用ManyToMany进行操作的方式(在我的项目中,我有很多这种类型的关系,因此可以肯定的是,不久的将来我会需要此帮助)。

UPDATE UPDATE

Ok, I'll like to keep this my track on this problem and I was doing some tests but without any helpful result, here are my tries: 好的,我想继续跟踪这个问题,我正在做一些测试,但是没有任何有益的结果,这是我的尝试:

First approach 第一种方法

public function filtrarOficinaRegionalPorTramite($tramite)
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb
        ->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite')
        ->from("AppBundle:OficinaRegional", "ofr")
        ->where("ofr.activo = :activo")
        ->leftJoin("AppBundle:TipoTramite", "ttr");

    $qb->setParameter('activo', TRUE);

    if ($tramite != NULL) {
        $qb->andWhere('ttr.id = :tramite');
        $qb->setParameter('tramite', $tramite);
    }

    echo $qb->getQuery()->getSQL();
    return $qb->getQuery()->getResult();
}

Didn't work since the result SQL from the previous code is this one: 无效,因为先前代码的结果SQL是以下代码:

SELECT n0_.nombre AS nombre0, n1_.nombre AS nombre1 
FROM nomencladores.oficina_regional n0_ 
LEFT JOIN nomencladores.tipo_tramite n1_ 
 ON (n0_.activo = ?) 

Second approach 第二种方法

public function filtrarOficinaRegionalPorTramite($tramite)
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb
        ->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite')
        ->from("OficinaRegional ofr")
        ->where("ofr.activo = :activo")
        ->leftJoin('ofr.TipoTramite ttr');

    $qb->setParameter('tramite', $tramite);

    if ($tramite != NULL) {
        $qb->where('ttr.id = :tramite');
        $qb->setParameter('tramite', $tramite);
    }

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

But got this error: 但是出现了这个错误:

Warning: Missing argument 2 for Doctrine\\ORM\\QueryBuilder::from(), called in /var/www/html/project.dev/src/AppBundle/Entity/Repository/RegionalOfficeRepository.php on line 25 and defined in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php line 721 警告:缺少Doctrine \\ ORM \\ QueryBuilder :: from()的参数2,在第25行的/var/www/html/project.dev/src/AppBundle/Entity/Repository/RegionalOfficeRepository.php中调用并在/ var /中定义www / html / project.dev / vendor / doctrine / orm / lib / Doctrine / ORM / QueryBuilder.php第721行

Third approach 第三种方法

After pass a huge amount of time trying to get things working I'm still having issues but this time I'm closer to fix them. 经过大量的时间尝试使事情正常运行后,我仍然遇到问题,但是这次我将更接近解决问题。 So, here is my latest shot, with this code: 因此,这是我最新的照片,带有以下代码:

public function filtrarOficinaRegionalPorTramite($tramite)
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb
        ->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite')
        ->distinct()
        ->from("AppBundle:OficinaRegional", "ofr")
        ->where("ofr.activo = :activo")
        ->leftJoin("ofr.tipoTramites", "ttr");

    $qb->setParameter("tramite", $tramite);

    if ($tramite != NULL) {
        $qb->andWhere("ttr.id = :tramite");
        $qb->setParameter("tramite", $tramite);
    }

    echo $qb->getQuery()->getSQL();
    return $qb->getQuery()->getResult();
}

I got this SQL: 我得到了这个SQL:

SELECT DISTINCT n0_.nombre AS nombre0,
                n1_.nombre AS nombre1
FROM nomencladores.oficina_regional n0_
  LEFT JOIN negocio.solicitud_usuario_oficina_regional n2_ ON n0_.id = n2_.tipo_tramite_id
  LEFT JOIN nomencladores.tipo_tramite n1_ ON n1_.id = n2_.oficina_regional_id
WHERE n0_.activo = ?
      AND n1_.id = ?;

Which is not wrong at all, but this is how the final SQL should be: 根本没错,但这就是最终的SQL应该是这样的:

SELECT DISTINCT n0_.nombre AS nombre0,
                n1_.nombre AS nombre1
FROM nomencladores.oficina_regional n0_
  LEFT JOIN negocio.solicitud_usuario_oficina_regional n2_ ON n0_.id = n2_.oficina_regional_id
  LEFT JOIN nomencladores.tipo_tramite n1_ ON n1_.id = n2_.tipo_tramite_id
WHERE n0_.activo = TRUE
      AND n1_.id = 1;

What I'm doing wrong? 我做错了什么?

It looks like your join column mappings are incorrect for TipoTramite, try flipping them around. 看来您的连接列映射对于TipoTramite不正确,请尝试将它们翻转。

 /**
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\OficinaRegional", inversedBy="tipoTramites", cascade={"persist"})
 * @ORM\JoinTable(name="negocio.solicitud_usuario_oficina_regional", schema="negocio",
 *      joinColumns={@ORM\JoinColumn(name="tipo_tramite_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="oficina_regional_id", referencedColumnName="id")}
 * )
 */

http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-unidirectional-with-join-table http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-unidirectional-with-join-table

As for the question marks, those are just parameters that will be filled in later. 至于问号,这些仅仅是参数,将在以后填充。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM