Как указать несколько условий соединения для отношений 1: 1 в Учении 2 - PullRequest
7 голосов
/ 03 февраля 2012

Документация гласит:

class Cart
{
    // ...

    /**
     * @OneToOne(targetEntity="Customer", inversedBy="cart")
     * @JoinColumn(name="customer_id", referencedColumnName="id")
     */
    private $customer;

    // ...
}

Эта аннотация представляет такой sql:

JOIN Customer c ON c.id = cart.customer_id

И проблема в том, что мне нужно добавить дополнительное сравнение, например:

JOIN Customer c ON c.id = cart.customer_id AND c.anotherField = <constant>

Есть какие-нибудь решения для этого?

UPD :

Реальное дополнительное условие, которое мне нужно сейчас, это <const> BETWEEN c.f1 AND c.f2

Ответы [ 2 ]

0 голосов
/ 24 марта 2016

Кажется, что не существует решения вашей проблемы, которое Doctrine могла бы решить автоматически.

Поскольку @ficuscr уже предоставил вам решение для запросов, есть еще одна вещь, которую нужно решить - проверитьдополнительных критериев и вернуть экземпляр Customer в получателе в случае успеха и NULL в случае невыполнения дополнительных критериев.

class Cart
{
    const VALUE = '<some_constant_value>';
    /**
     * @OneToOne(targetEntity="Customer", inversedBy="cart")
     * @JoinColumn(name="customer_id", referencedColumnName="id")
     */
    private $customer;

    // ...

    /**
     * @return Customer|null
     */
    public function getCustomer()
    {
        if ($this->customer->getField1() <= self::VALUE
            && $this->customer->getField2() >= self::VALUE
        ) {
            return $this->customer;
        }

        return null;
    }
}

Если это было отношение «один ко многим», API фильтрации коллекций (aka Criteria) можно использовать для фильтрации коллекции, созданной сопоставлениями:

use Doctrine\Common\Collections\Criteria;

class Cart
{
    const VALUE = '<some_constant_value>';
    /**
     * @OneToMany(targetEntity="Customer", mappedBy="cart")
     */
    private $customers;

    // ...

    /**
     * @return Customer[]|ArrayCollection
     */
    public function getCustomers()
    {
        $expr = Criteria::expr();
        $criteria = Criteria::create()
            ->where($expr->andX(
                $expr->lte('field1', self::VALUE),
                $expr->gte('field2', self::VALUE)
            ));

        return $this->patientProblems->matching($criteria);
    }
}
0 голосов
/ 08 февраля 2012

вы можете использовать ключевое слово WITH, чтобы указать дополнительные условия соединения, как вы можете видеть в некоторых примерах .

Я думаю, это должно помочь вам:

SELECT l, c FROM location
INNER JOIN Customer c
WITH CURRENT_TIMESTAMP() BETWEEN c.f1 AND c.f2
WHERE CURRENT_TIMESTAMP() BETWEEN l.f1 AND l.f2

я удалил предложение ON, потому что я думаю, что нет необходимости явно указывать поля ON объединения, если только они не являются "стандартными" (идентификатор каждой сущности)

также обратите внимание на вызов CURRENT_TIMESTAMP(), который переводится в MySQL NOW(). посмотрите список других довольно полезных агрегатных функций и выражений здесь

...