2011-10-11 64 views
11

我有一个项目,我处理客户订单。其中一些订单是通过Amazon.com制作的。所以我有一个Order实体和一个扩展它的AmazonOrder实体。 AmazonOrder添加的一件事是AmazonOrderId。Doctrine2:多态查询:在子类的属性上搜索

我有要求实施广泛的搜索功能。用户可以在文本框中输入一些东西,并在一个大的where子句中用于一堆表达式。因此,例如,如果用户搜索“111”,则结果包括任何具有以111开头的ID的订单,任何订单被发送到以111开头的邮政编码,发送到“111 Main St”的任何订单等。

这个东西是用查询生成器创建的查询实现的,该查询具有大的orX()表达式。

现在,我想匹配所有订单,但是如果它们是AmazonOrder,也会匹配AmazonOrderId。

而且我卡住了 - 我怀疑它可能无法

这里是我如何建立查询:

$qb->select('o,s')->from('PMS\Entity\Order', 'o');  
$qb->leftJoin('o.shippingInfo','s'); 
$qb->andWhere('o.status = :status'); 
$qb->setParameter('status',$status); 
$qb->andWhere(
    $qb->expr()->orX(
     $qb->expr()->like('o.id',':query') 
     $qb->expr()->like('s.address',':query') 
     $qb->expr()->like('s.city',':query') 
    ) 
); 
$qb->setParameter('query',$userQuery .'%'); 

$orders = $qb->getQuery()->getResult(); 

我无法弄清楚如何添加条件,大致说,“或(订单是一个AmazonOrder和AmazonOrderId LIKE' $ userQuery%')”

任何人有任何见识?要么处理这个问题的方法,要么至少证明这样做是不可行的?

回答

21

这里是另一种解决方案是使用Doctrine 2.4为我的作品:

$qb->select('o') 
    ->from('Order', 'o') 
    ->leftJoin('AmazonOrder', 'ao', 'WITH', 'o.id = ao.id') 
    ->andWhere('o.id like :query or ao.amazonOrderId like :query') 
    ->setParameter('query', $someQuery); 

你刚刚离开,加入了实体上的自身特定的子类。 (你可以使我的简单查询适应你的用例。)

我试过这一次,但它似乎工作。

+0

即使对于具有复合键的实体,它也可以很好地工作。 – Wilt

+0

如果我可以再次投票这个答案,我会做到这一点! – Wilt

+0

感谢您的支持!在DQL记录中: SELECT o FROM Order LEFT JOIN AmazonOrder ao WITH o.id = ao.id – omgitsdrobinoha

2

嗯,我在我上一个教义项目中遇到了类似的问题。

有一次,它只是一个字段,所以我把它移到父类 - 不是最好的解决方案,但工作。在另外一些情况下,太多的属性会混淆父类。我做了一个本地sql查询来搜索并获取记录ID,然后使用一个WHERE IN (...) dql来获取实体。

一个折中的可能是学说ResultSetMapping它可以映射本地SQL查询,直接的实体,尽管每次我与它的工作时间,我觉得这是很笨拙的使用,并为两个查询的开销(取IDS &取的entites)作为上面列出的是可以忽略的。

也许你可以用INSTANCEOF运营商在你的WHERE条款中完成一些事情,虽然我不认为教义会足够聪明以你想要的方式识别它。

+0

谢谢Max。我现在通过用UI来解决这个问题。这不是最佳的,我很快会重新访问它。我真的很想避免把东西移到超类。听起来我认为没有简单的解决方案是对的。如果我在重新审视这个问题时想出了一些聪明的东西,我会让你知道的。 – timdev

+0

另请参阅http://stackoverflow.com/a/19942431/560114 –