私はSymfony2で、次のモデルの教義を使って実装を行っています。
親と研修生の間の継承と関連付け(1対1)は、以下に示すように、単一テーブル継承を使用して実装されています。
Parents\ParentsBundle\Entity\Parents:
type: entity
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: type
type: string
discriminatorMap:
parents: Parents
trainee: Parents\TraineeBundle\Entity\Trainee
table: Parents
repositoryClass: Parents\ParentsBundle\Repository\ParentsRepository
id:
id:
type: integer
generator:
strategy: AUTO
fields:
firstname:
type: string
length: 250
lastname:
type: string
length: 250
dob:
type: date
nullable: true
lifecycleCallbacks:
prePersist: [ setDateDeCreationValue ]
manyToMany:
trainings:
targetEntity: Training\TrainingBundle\Entity\Training
mappedBy: parents
orphanRemoval: true
cascade: ["all"]
oneToOne:
trainee:
targetEntity: Parents\TraineeBundle\Entity\Trainee
inversedBy: parents
cascade: ["all"]
joinColumns:
trainee_id:
referencedColumnName: id
indexes:
nom_prenoms_idx:
columns: [ firstname, lastname ]
Parents\TraineeBundle\Entity\Trainee:
type: entity
extends: Parents\ParentsBundle\Entity\Parents
repositoryClass: Parents\TraineeBundle\Repository\TraineeRepository
manyToMany:
skills:
targetEntity: Training\SkillBundle\Entity\Skill
mappedBy: trainees
oneToOne:
parents:
targetEntity: Parents\ParentsBundle\Entity\Parents
mappedBy: trainee
Trianing\SkillBundle\Entity\Skill:
type: entity
table: Skill
repositoryClass: Training\SkillBundle\Repository\SkillRepository
id:
id:
type: integer
generator:
strategy: auto
fields:
title:
type: string
length: 80
unique: true
description:
type: string
length: 250
nullable: true
manyToMany:
trainees:
targetEntity: Parents\TraineeBundle\Entity\Trainee
inversedBy: skills
cascade: ["all"]
joinTable:
name: trainess_skills
joinColumns:
skill_id:
referencedColumnName: id
nullable: false
onDelete: CASCADE
inverseJoinColumns:
trainee_id:
referencedColumnName: id
nullable: false
uniqueConstraints:
titre_UNIQUE:
columns:
- titre
ただし、トレーニンググループのスキルで「資格がある」親のリストから次のような人を除外しようとしています。
期待される結果を得ることができる次のSQLクエリがありますが、関連付けがエンティティにリンクしているため、Doctrineで機能するSQLクエリを使用できません。SQLクエリ
SELECT p.*
FROM Parents p
LEFT JOIN training_formations tf
ON p.id = tf.parents_id
LEFT JOIN Training t
ON tf.training_id = t.id
LEFT JOIN Parents trainee
ON p.intervenant_id = trainee.id
LEFT JOIN trainees_skills ts
ON trainee.id = ts.trainee_id
WHERE t.id=@trainingId and (t.skill_id <> ts.skill_id or p.trainee_id is null);
教義の質問:
$qb = $this->createQueryBuilder('p');
$qb->select('p')
->leftJoin('p.trainings', 't')
->leftJoin('p.trainee','tr')
->leftJoin('tr.skill','s')
->where('t.id = :trainingId')
->andWhere($qb->expr()->orX(
$qb->expr()->neq('t.skill','tr.skill'),
$qb->expr()->isNull('p.trainee')
)
)
->setParameter('trainingId', $trainingId)
->orderBy('p.firstname', 'ASC');
return $qb;
結果のクエリはPathExpressionエラーをスローします。これは、外部キーで「IDENTITY()」メソッドを使用して修正しようとしましたが、utは機能しませんでした。
私は何かを逃したか、何かを間違って実装しましたか?
更新されたDoctrineクエリの下に解決策が見つかりました:
$qb = $this->createQueryBuilder('p');
$qb->select('p')
->leftJoin('p.trainings', 't')
->leftJoin('p.trainee','tr')
->leftJoin('tr.skill','s')
->where('t.id = :trainingId')
->andWhere($qb->expr()->orX(
$qb->expr()->neq('t.skill','s.id'),
$qb->expr()->isNull('s.id')
)
)
->setParameter('trainingId', $trainingId)
->orderBy('p.firstname', 'ASC');
return $qb;
ただし、さまざまな読み方から、ここで使用されている継承よりもコンポジションの方が適しているようです。しかし、それは別のトピックです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加