Отношения: Reference, OneToMany, ManyToMany
Связи между таблицами описываются полями Reference (многие к одному), OneToMany и ManyToMany. При выборке отношений один-ко-многим с лимитом или пагинацией необходимо использовать QueryHelper::decompose() или disableDataDoubling(), чтобы избежать декартова произведения и искажения работы LIMIT.
Прогресс хранится в этом браузере. Войдите, чтобы сохранить его в аккаунте.
Что нужно понимать
-
1
Reference (ссылка)
-
2
OneToMany (один-ко-многим)
-
3
ManyToMany (многие-ко-многим)
Материалы
Официальная документация
Материалы BXMax
Проверь себя
Запрос с setLimit(5) и addSelect('AUTHORS') вернул три книги, у одной не все авторы. Почему?
LIMIT применяется к строкам SQL после LEFT JOIN, а не к книгам: пять строк — это книги, умноженные на авторов. Лечится QueryHelper::decompose() с fairLimit или двумя запросами: сначала ID книг с лимитом, потом связи по этим ID.
Заказчик удалил издательство через PublisherTable::delete($id), а у книг остался PUBLISHER_ID, хотя в связи задан CascadePolicy. Где искать?
В способе удаления. Политики каскада, включая SET_NULL по умолчанию у OneToMany, применяет EntityObject::delete() при удалении объекта. Статический DataManager::delete() по ключу про связи не знает и удаляет только строку.
Чем плох фильтр по множественной связи where('AUTHORS.NAME', 'A%') при постраничной выборке?
Условие по 1:N уходит в JOIN, строки основной сущности дублируются, и LIMIT считает дубли. disableDataDoubling() переводит такой фильтр в подзапрос ID IN (SELECT ...), и выборка снова считает книги, а не строки.
Когда ManyToMany не подходит, хотя связь именно многие-ко-многим?
Когда у связи есть свои данные, например QUANTITY книги в магазине. ManyToMany скрывает промежуточную сущность и не даёт ни читать, ни обновлять её поля. Тогда описывают сущность-посредник и связывают её с обеими сторонами через OneToMany.
Не сходится?
Спросите ассистента BXMax: он знает документацию и материалы сайта по этой теме.
Знаете материал лучше?
Предложите ссылку: после проверки она появится в этом разделе.
Войти, чтобы предложить