Отношения Zend Framework - определение имен столбцов в findManyToManyRowset()?
-
08-07-2019 - |
Вопрос
Я работаю над приложением, разработанным с использованием Zend Framework.Я определил отношения в моделях и могу с удовольствием их использовать, например:
$rowset = $row->findManyToManyRowset('People', 'Jobs');
Однако я столкнулся с проблемой, когда возвращаемый набор строк имеет одинаковые имена столбцов в 'People' и 'Jobs', и, следовательно, объединяет ключи массива, теряя часть данных из конечного набора строк.
Я понимаю, что могу пройти Zend_Db_Select
возражать против findManyToManyRowset()
в качестве одного из параметров, но не могу найти никакой документации, объясняющей, как использовать его в данном случае, например:
$select = $this->select()->from(array(
'p' => 'people',
'j' => 'jobs'
),
array(
'person_id' => 'p.id',
'job_id' => 'j.id',
'person_code' => 'p.code',
'job_code' => 'j.code'
)
);
Если я попытаюсь использовать приведенный выше код, я получу такое сообщение, как:
Error: No reference rule "" from table People to table Jobs
Кто-нибудь может просветить меня о том, как это должно быть сделано?Я знаю, что мог бы изменить имена своих столбцов в базе данных, но я бы предпочел изменить код, а не перепроектировать структуру моей базы данных и обновлять весь связанный код.
Примечание:без какой-либо формы псевдонимирования столбцов, как указано выше, возвращаемый набор строк выглядит следующим образом (т. е. он объединяет столбцы с одинаковыми именами):
[_data:protected] => Array
(
[id] => 1
[code] => SX342
)
Ваше здоровье,
Мэтт
Решение
Моя первая рекомендация заключается в том, что вы не должны называть столбцы такими общими именами, как id
и code
.Эти имена бессмысленны, и, как вы обнаружили, они также приводят к коллизиям при извлечении результатов в ассоциативном массиве.
Вы также неправильно используете интерфейс Выбора.Вы должны указать только одну таблицу для каждого from()
позвонить или join()
звони.
Наконец, я никогда не пытаюсь выполнять сложные запросы через Zend_Db_Table
интерфейс взаимоотношений.Он предназначен только для простых случаев.Если у вас есть более сложный запрос, просто напишите SQL-запрос явно.
Смотрите также Как выполнить объединенный запрос в интерфейсе ZF tables?
Другие советы
Я знаю, что этот ответ приходит немного с опозданием, но вот на что следует обратить внимание.
1) findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule, $matchRefRule, $select);
-- если вы проходите мимо Zend_Db_Table_Select
вы наверняка захотите пройти null
ради правил.
2) Тот Zend_Db_Table_Select
перешедший в findManyToManyRowset()
должен быть создан из $matchTable
и можно с уверенностью предположить , что в предложениях where i
является псевдонимом для таблицы пересечений, и m
является псевдонимом для таблицы совпадений.
3) В случае столкновений, m
получит имя ключа в ассоциативном массиве, возвращаемом в php.Выполненный запрос выглядит следующим образом:
SELECT
`i`.*, `m`.*
FROM
`interscetTable` AS `i`
INNER JOIN
`matchTable` AS `m`
ON
`i`.`fk_m` = `m`.`pk` WHERE (`i`.`fk_o` = ?)
4) Несмотря ни на что, возвращаемое значение findManyToManyRowset()
будет набором строк, созданным из $matchTable
итак, если вам нужно получить какую-либо информацию из пересекающейся таблицы, а также данные для таблицы совпадений, вам, вероятно, потребуется пользовательский Zend_Db_Select
и избегайте использования Zend_Db_Table
материал для сопоставления данных в любом случае.
Итак, рабочий пример, использующий "People" в качестве таблицы соответствия, "Workers" в качестве таблицы пересечения и, скажем, "Clients" в качестве исходной таблицы..Предполагая для этого примера, что таблицы связывают друг с другом что-то вроде:Люди.id:...
-> рабочие.person_id:client_id:job_id
-> клиенты:id:...
$client = $clientTable->fetchRow(); /// grab a random client
// fetch all people that have worked for the client ordered by their last name.
$client->findManyToManyRowset("People", "Workers", null, null,
$peopleTable->select()->order('m.lastname'));
// fetch all people that have worked for the client ordered by their hire date:
// `workers`.`hiredate`
$client->findManyToManyRowset("People", "Workers", null, null,
$peopleTable->select()->order('i.hiredate'));