如何按Doctrine 2中没有@Column注释的实体属性进行搜索?

时间:2014-10-24 13:37:36

标签: php orm doctrine-orm doctrine entity

 /**
* @ORM\Entity
*/
class Order extends BaseEntity
{
// this is trait for @Id
use Identifier;

/**
* @ORM\Column(type="integer")
*/
protected $costPerUnit;

/**
* @ORM\Column(type="integer")
*/
protected $numberOfUnits;

// i want to search by this property
protected $totalCost;

public function getTotalCost()
{
 return $this->numberOfUnits * $this->costPerUnit;
}

}

我有一个这样的实体,我希望能够做到例如

$orderRepository->findOneByTotalCost('999')
$orderRepository->findBy(['totalCost' => '400']);

Doctrine2中有可能吗?或者我会采用不同的方式吗?

2 个答案:

答案 0 :(得分:2)

就像我在评论中所说的那样,你可能正在努力解决首先不应该发生的问题。尽管如此,使用doctrine可以通过各种方式将SUM值映射到属性 Check the aggregate field docs找出最能解决问题的方法。

在我看来,你使用的实体比实际更多:实体代表数据库中的记录,Doctrine是DBAL。使用实体(或存储库)搜索数据 查询数据库。您可以通过向实体管理器或自定义存储库类添加自定义方法来解决问题,该类将查询计算所有实体的totalCost值所需的所有数据,并仅返回您需要的数据。或者,使用DBAL中的连接查询您之后的ID(例如),然后使用这些值来获取实际实体。或者,就像我之前说过的那样:使用聚合字段。


您展示的findOneByTotalCostfindBy示例存在的问题是,第一个要求您自己编写方法 Called findOneByTotalCost。使用findBy的问题只是你的参数格式不正确:数组应该是关联的:使用映射的列名作为键,值是你想要查询的值:

$repo->findBy(
    ['totalCost' => 400]
);

是您要找的,而不是['totalCost', 400]。至于实体本身,您需要添加注释:

是的,从您在doc-blocks中使用@ORM\Entity注释来判断,应该这样做:

/**
 * @ORM\Column(type="string", length=255)
 */
protected $regioun = 'Spain';

更新表格,您将能够:

$entities = $repo->findBy(
    ['region' => 'Spain']
);

不要忘记此代码表示数据库中的表:您可以搜索任何字段,但可以使用索引,您可以通过在类定义顶部添加注释来执行索引:

/**
 * @ORM\Table(name="tblname", indexes={
 *  @ORM\Index(name="region", columns={"region"})
 * })
 */
class Foo
{}

与往常一样:在数据库中,索引重要

答案 1 :(得分:1)

您应该在实体存储库中编写一个方法findOneByTotalCost,如:

public function findOneByTotalCost ($queryParams){

    $query = 'select o
                from <yourEntity> o
               where o.numberOfUnits * o.costPerUnit = :myParam';


    $dql = $this->getEntityManager()->createQuery($query);
    $dql->setParameter('myParam', $queryParams);       

    return $dql ->execute();


}

他们,$ orderRepository-&gt; findOneByTotalCost('999')应该有效。