2016-05-30 57 views
0

我在Symfony2中的工作實現與以下模型的原則。 enter image description here從繼承和關聯場景的主義查詢問題

  • 父母可以申請一個/多個培訓(S)
  • 培訓是基於特定的技能,但是你可以在不同的日期爲同一技能培訓多。
  • 一旦家長參加培訓,他可以被標記爲與所培訓的技能相關的「合格」,併成爲實習生。
  • 家長可以參加在同一技能的多個培訓,但對於給定的技能將只標有「資格」只有一次
  • 許多型動物技能

的繼承和協會培訓生可以「合格」

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 

但是,即時通訊尋求家長的列表中排除要在技能從培訓「合格」:家長和見習之間(一對一),如下圖所示一直使用單表繼承中實現這些人是:

  1. 對技能的所有準備見習

我有下面的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 [email protected] 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做不行。

我錯過了什麼,或者是否有過一些事情嗎?

回答

0

找到了解決辦法,下面的更新查詢學說:

$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; 

然而,從不同的閱讀似乎是一個組合會更適合比這裏使用的繼承。但那是另一個話題。