Как контролировать порядок запроса отношения

Есть ли какая-то магия в Symfony/doctrine с моделью под названием JosVmOrderHistory?

У меня есть эта выдержка schema.yml:

JosVmOrder:
  tableName: jos_vm_orders
  columns:
    order_id: { type: integer(4), primary: true, autoincrement: true }
    user_id: { type: integer(4), notnull: true }
    vendor_id: { type: integer(4), notnull: true }
    order_number: { type: string(32), notnull: false }
    user_info_id: { type: string(32), notnull: false }
    order_total: { type: 'decimal(15, 5)', notnull: true }
    order_subtotal: { type: 'decimal(15, 5)', notnull: false }
    order_tax: { type: 'decimal(10, 2)', notnull: false }
    order_tax_details: { type: string(), notnull: true }
    order_shipping: { type: 'decimal(10, 2)', notnull: false }
    order_shipping_tax: { type: 'decimal(10, 2)', notnull: false }
    coupon_discount: { type: 'decimal(12, 2)', notnull: true }
    coupon_code: { type: string(32), notnull: false }
    order_discount: { type: 'decimal(12, 2)', notnull: true }
    order_currency: { type: string(16), notnull: false }
    order_status: { type: string(1), notnull: false }
    cdate: { type: integer(4), notnull: false }
    mdate: { type: integer(4), notnull: false }
    ship_method_id: { type: string(255), notnull: false }
    customer_note: { type: string(), notnull: true }
    ip_address: { type: string(15), notnull: true }
  relations:
    User: { class: JosUser, local: user_id, foreignAlias: OrderList }
    LatestVmOrderDetail: { class: LatestVmOrderDetail, local: order_id, foreign: order_id }

JosVmOrderHistory:
  tableName: jos_vm_order_history
  columns:
    order_status_history_id: { type: integer(4),primary: true, autoincrement: true }
    order_id: { type: integer(4) }
    order_status_code: { type: string(1) }
    date_added: { type: timestamp(25) }
    customer_notified: { type: integer(4), notnull: false }
    comments: { type: clob(16777777), notnull: false }
  relations:
    Order: { class: JosVmOrder, local: order_id, foreign: order_id }
    OrderStatus: { class: JosVmOrderStatus, local: order_status_code, foreign: order_status_code }

Во-первых, ForeignAlias ​​JosVmOrderHistory — это «JosVmOrderHistory», а не «JosVmOrderHistoryList», как я предполагал.

Во-вторых, в model/doctrine/Order.class.php у меня есть следующая функция:

function getPaymentStatus(){

    $historyList = $this->getJosVmOrderHistory();
    if (count($historyList)){

        return $paymentStatus = $historyList[0];
    }else{
        return $paymentStatus = null;
    }
}

$historyList всегда находится в порядке убывания order_status_history_id. Я даже добавил в model/doctrine/JosVmOrderHistoryTable.class.php:

public function createQuery($alias){

    return parent::createQuery($alias)->orderBy('order_status_history_id asc');


}

но он остается в порядке убывания..

Изменить: я обновил тему - похоже, эта проблема сводится к тому, как управлять OrderBy реляционного запроса. createQuery, похоже, вообще не вызывается.


person jdog    schedule 19.07.2011    source источник
comment
Рассматривали ли вы просто сортировку массива вместо того, чтобы пытаться изменить поведение Doctrine? В противном случае запрашивайте связанные данные напрямую, а не обращайтесь к ним через геттер другого объекта.   -  person Dan Grossman    schedule 20.07.2011
comment
Спасибо, Дэн, не подумал об этом. Мне это нужно из соображений скорости, в основном отношение должно быть включено в table_method, и пользовательская сортировка должна работать. Теперь я создал представление MySQL и создал для него отношение.   -  person jdog    schedule 28.07.2011


Ответы (1)


Если вам это нужно из соображений скорости, вы не должны загружать всю историю заказов из БД, если вас интересует только первый, вместо этого используйте запрос, например:

function getPaymentStatus(){

    $historyList = Doctrine::getTable('JosVmOrderHistory')->createQuery()->where('order_id = ?', $this->order_id)->orderBy('order_status_history_id')->limit(1)->execute();
    if (count($historyList)){

        return $paymentStatus = $historyList[0];
    }else{
        return $paymentStatus = null;
    }
}

При этом можно автоматически влиять на сортировку, больше похожую на то, что вы пытались сделать с помощью слушателя. В прошлом я создал общее поведение сортировки, которое вы можете использовать, например:

  actAs:
    DefaultSort: { column: title }
person Joshua Coady    schedule 29.07.2011
comment
Спасибо, я пришел к такому же выводу. Проблема скорости заключается не в вызове getPaymentStatus(), а в методе таблицы, для которого, однако, потребуется подзапрос таблицы (см. select-with-join" title="doctrine subquery in select with join">stackoverflow.com/questions/6434310/). В конце концов я использовал представление MySQL и присоединился к нему в методе table_method. Тем не менее, можете ли вы уточнить, где будет находиться моя функция Listener? - person jdog; 29.07.2011
comment
Я реализовал прослушиватель как поведение, но я думаю, что если бы вы хотели его только для этого одного класса, он вошёл бы в класс во время установки. Как и в функции setTableDefinition(), добавьте прослушиватель с помощью $this->addListener(). Сам слушатель должен быть отдельным классом. Если вы используете исключительно для этого класса, просто поместите его определение в тот же файл. Класс прослушивателя должен расширять Doctrine_Record_Listener и реализовывать функцию preDqlSelect(). - person Joshua Coady; 29.07.2011
comment
для функции preDqlSelect вы можете использовать что-то вроде кода: - person Joshua Coady; 29.07.2011
comment
$query = $event->getQuery(); $orderby = $query-›getDqlPart('orderby'); // применяем сортировку по умолчанию, только если не задана другая сортировка if(count($orderby) == 0) { $query-›orderBy(order_status_history_id); } - person Joshua Coady; 29.07.2011