перевести сырой MySQL в Doctrine 1.2 - PullRequest
0 голосов
/ 23 декабря 2011

Я потратил немного времени на перевод следующего необработанного запроса MySQL, который был протестирован и очень хорошо работает, в доктрину 1.2:

SELECT
    r.name AS regionname,
    s.name AS statename
FROM
    job j
LEFT JOIN
    community c ON c.id = j.community_id
LEFT JOIN
    state s ON s.id = c.state_id
LEFT JOIN
    region r ON r.id = s.region_id
WHERE
    r.id = 1

Это не работает:

$q = Doctrine_Query::create()  
    ->select('r.name AS regionname', 's.name AS statename')
    ->from('job j')
    ->leftJoin('community c ON c.id = j.community_id')
    ->leftJoin('state s ON s.id = c.state_id')
    ->leftJoin('region r ON r.id = s.region_id')
    ->where('r.id = 1')
    ->execute();

Вот моя структура БД, если она полезна:

job:
columns:
  id
  community_id
relations:
  community:  local_key: community_id, foreign_key: id, foreignAlias: Communitys

community:
columns:
  id
  state_id
relations: 
  state: local_key: state_id, foreign_key: id, foreignAlias: States

state:
columns:
  id
  name
  region_id
relations:
  region: local_key: region_id, foreign_key: id, foreignAlias: Regions

region:
columns:
  id
  name

1 Ответ

0 голосов
/ 24 декабря 2011

Я тоже заметил то же самое.Выполнение объединений в Doctrine 1.2 немного отличается от mysql.Чтобы выполнить объединение, вы должны воспользоваться преимуществами отношений, которые Doctrine создает в каждом компоненте в вашем случае класса заданий.

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

  $this->hasOne('community as Communitys', array(
         'local' => 'community_id',
         'foreign' => 'id'));

Возвращаясь к вашему вопросу, чтобы выполнить объединение, необходимо сослаться на псевдоним таблицы, гдевнешний ключ принадлежит.Например, если вы хотите присоединиться к таблице сообщества с псевдонимом Сообщество:

->leftJoin('j.Community')

вместо

community c ON c.id = j.community_id

Обратите внимание, что я не сказал присоединиться к идентификатору, потому что в Doctrine 1.2это уже подразумевается.Однако вы можете присоединиться к чему-то другому.

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

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

Итак, вы сказали, что хотите присоединить сообщество к государствам в текущем запросе так, как вы должны это сделать:

// join job and community first
->from('job j')
->leftJoin('j.Community c')
// join community to state since they are the ones that are related
->leftjoin('c.States s')

Отсюда, я надеюсь, вы сможете увидеть шаблон.В конце концов, если вы посмотрите на это, идея объединения остается такой же с сырым sql, единственное отличие - синтаксис:

Синтаксис SQL:

LEFT JOIN
    community c ON c.id = j.community_id

Синтаксис DQL:

->leftJoin('j.Community c')

В любом случае, чтобы ответить на ваш вопрос, вот как можно сделать соединение:

$q = Doctrine_Query::create()  
    ->select('*')
    ->from('job j')
    ->leftJoin('j.Community c')
    ->leftJoin('c.State s')
    ->leftJoin('s.Region r')
    ->where('r.id = 1')
    ->execute();
...