2014-07-12 20 views
2

我需要“连接”HolidayPackageDiscount(一对一)的实例,并且能够在从存储库获取数据时获取连接。即:如何在没有“真正的”外键的情况下获取Doctrine中的连接?

// Inside a method of HolidayPackageRepository repository class 
$qb = $this->createQueryBuilder($alias = 'hp'); 
$qb->leftJoin("$alias.discount", 'd') 
    ->addSelect('d'); // fetch join 

问题discount表被删除并重新填补每几个小时,所以discount_id不能成为一个真正的外键。但是标识符可能保持不变:

/** 
* @ORM\Entity() 
* @ORM\Table("holiday_package") 
*/ 
class HolidayPackage 
{ 
    /** 
    * @ORM\Column(name="discount_id", type="integer", nullable=true) 
    * 
    * @var null|Discount 
    */ 
    private $discount; 
} 

如何在没有真正外键的情况下获取连接?

+0

您可能只需要进行第二次查询或下拉到SQL。 – Cerad

+0

@Cerad这是我目前正在做的,我正在寻找更好的方式... – gremo

回答

0

您可以在实体指定的关系,即使你没有在你的数据库

/** 
* @ORM\Entity() 
* @ORM\Table("holiday_package") 
*/ 
class HolidayPackage 
{ 
    /** 
    * @ORM\Column(name="discount_id", type="integer", nullable=true) 
    * 
    * @var null|int 
    */ 
    private $discountId; 


    /** 
    * @ORM\OneToOne(targetEntity="Discount") 
    * @ORM\JoinColumn(name="discount_id", referencedColumnName="discount_id") 
    * 
    * @var null|Discount 
    */ 
    private $discount; 
} 

外键这样你的加入应该工作。

+0

听起来像一个“黑客”对我... – gremo

+0

@gremo我不同意。它指定了一个不是外键的关系。它允许在SQL中进行连接,即使没有定义外键也是如此。 – flec

+0

您正在定义一个“标准”列“discount_id”,然后是一对一关系,它将创建同一列“discount_id”。如果我是对的,一对一关系拥有目标实体,因此它拥有外键。它可能工作(我没有测试它),但如果你切换注释的顺序呢?它会工作吗?顺便说一句,我想另一种方法:使用标准的外键,但在更新/同步过程中禁用它们,防止级联删除儿童。你怎么看? – gremo

1

我从来没有真正尝试过它,但根据文档,从2.4开始,只要两个实体都被映射,就可以在任意列上连接实体,并使用“常用”JOIN ... WITH语法:

SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email 

不过,我不知道这是否会允许在这个例子中,你实际上取指令 - 加入“黑名单”之上,否则将只是让你限制的结果。

相关问题