Когда стоило бы поддерживать обратную связь в Doctrine2? - PullRequest
13 голосов
/ 10 августа 2011

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

Я говорю это, потому что кажется, что вы часто хотели бы идти от Одной стороны ассоциации Один-ко-многим, а не отМного сторон.Например, я хотел бы получить все активные номера телефонов пользователя, а не все активные номера телефонов и связанных с ними пользователей.Это становится более важным, когда вам нужно пройти через несколько отношений «один ко многим», например, если вы хотите видеть всех пользователей с MissedCall за последние два дня (MissedCall-> PhoneNumber-> User).

ThisВот как выглядит простой случай с обратной ассоциацией:

SELECT * FROM User u
LEFT JOIN u.PhoneNumbers p WITH p.active

Это сделало бы его более разумным, если бы в DQL был способ перебросить данное отношение в противоположном направлении, как в следующем необработанном SQL:

SELECT * FROM User u
LEFT JOIN PhoneNumber p ON p.User_id = u.id AND p.active

Может кто-нибудь объяснить, почему он дает этот совет, и в каких случаях его стоит игнорировать?

- Правка -

Если есть смягчающие факторы или другие обходные пути, пожалуйста, дайте мне простой пример кода или ссылку.

Я не вижу никакого способа пройти обратное отношение, когда это обратное не определено, поэтому я собираюсьпредположить, что создание пользовательского DQL не на самом деле является решением - есть некоторые объединения, тривиальные с SQL, которые невозможны с DQL, и гидратация, вероятно, не будет работатьYWAY.Вот почему я не понимаю, почему добавление обратных отношений - плохая идея.

Ответы [ 2 ]

4 голосов
/ 20 августа 2011

Используя Doctrine, я определяю отношения только тогда, когда они нужны. Это означает, что все определенные отношения фактически используются в кодовой базе.

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

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

Определение только необходимых отношений позволит вам лучше контролировать то, как вы и ваша команда проходите по вашим данным, и уменьшать лишние или слишком большие запросы

Обновлено 22.08.2011

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

  • \Entity\Post имеет определенное отношение к \Entity\User и \Entity\Comment
    • Используйте $post->user, чтобы получить автора
    • Используйте $post->comments, чтобы получить все комментарии
  • \Entity\User имеет определенное отношение как к \Entity\Post, так и к \Entity\Comment
    • Используйте $user->posts, чтобы получить все сообщения пользователя
    • Используйте $user->posts, чтобы получить все комментарии пользователей
  • \Entity\Comment имеет отношение только к \Entity\User
    • Используйте $comment->user, чтобы получить автора
    • Невозможно использовать $comment->post, так как я не получаю сообщение, которому оно принадлежит в моем приложении

Я бы не думал о них как об "обратных" отношениях. Думайте о них как о «двунаправленных», если использование данных в обоих направлениях имеет смысл. Если это не имеет смысла, или вы не будете использовать данные наоборот, не определяйте их.

Надеюсь, это имеет смысл

2 голосов
/ 10 августа 2011

Я думаю, что это отличный вопрос, и с нетерпением жду ответов других.

Как правило, я истолковал приведенный ниже совет к следующему практическому правилу:

Если мне не нужен доступ к (обратной) связи внутри моей сущности, то я обычно делаю ее однонаправленной.В вашем примере с пользователями и (пропущенными) вызовами я бы, вероятно, оставил его однонаправленным, и позволил бы некоторому классу обслуживания или репозиторию обрабатывать сборку настраиваемого DQL для странного случая, когда мне нужно было получить список всех пользователей с недавними пропущенными вызовами.Это случай, который я бы назвал исключительным - в большинстве случаев меня просто интересуют звонки конкретного пользователя, поэтому однонаправленные отношения работают (по крайней мере, пока у меня не так много записей, что я чувствую необходимость оптимизировать).

...