Doctrine和X中的动态参数()

时间:2016-10-05 10:45:13

标签: php doctrine

根据传递的参数,我正在寻找使教学DQL语句的andX部分动态的解决方案:

private function getDiscountPrice(int $weighting, Article $article, Customer $customer, array $args) {

// Get the query builder
$qb = Shopware()->Models()->createQueryBuilder();
$params = new ArrayCollection();

foreach($args as $key => $arg):
    $params->set($key,$arg);
endforeach;

$qb->select('discount')
    ->from('PhaBase\Models\Discount','discount')
    ->where(
        $qb->expr()->andX(
                $qb->expr()->eq('discount.kdNr',':kdNr'),
                $qb->expr()->eq('discount.pzn',':pzn'),
                $qb->expr()->isNotNull('discount.kdNr'),
                $qb->expr()->isNotNull('discount.pzn')
        )
    )
    ->setParameters($params->toArray());

$discount = null;

try {
    $discount = $qb->getQuery()->getOneOrNullResult();
} catch (NonUniqueResultException $e) {
    // @TODO Add log entry to inform about Exception
    return null;
}

我想以与参数相同的方式构建andX()参数的内容,但我不知道如何将动态参数传递给此方法。

感谢您的任何想法, 迈克尔

2 个答案:

答案 0 :(得分:1)

这是解决方案 - 刚刚找到它:

private function getDiscountPrice(int $weighting, Article $article, Customer $customer, array $args) {

// Get the query builder
$qb = Shopware()->Models()->createQueryBuilder();

$params = new ArrayCollection();
$conditions = new ArrayCollection();

foreach($args as $key => $arg):
    $params->set($key,$arg);
    $conditions->add($qb->expr()->eq('discount.'.$key,':'.$key));
endforeach;

$conditions = call_user_func_array(array($qb->expr(), 'andX'), $conditions->toArray());

$qb->select('discount')
    ->from('PhaBase\Models\Discount','discount')
    ->where($conditions)
    ->setParameters($params->toArray());

$discount = null;

try {
    $discount = $qb->getQuery()->getOneOrNullResult();
} catch (NonUniqueResultException $e) {
    // @TODO Add log entry to inform about Exception
    return null;
}

// If a discount was found calculate the price for this discount and return it.
if (!is_null($discount)):
    $discountPrice = $this->calculateDiscountPrice($article, $discount, $customer);

答案 1 :(得分:0)

您可以将add()个附加表达式直接添加到andX()orX()

您可以将表达式直接添加到ArrayCollection表达式中,而不是将表达式添加到andX中(如果内部确实包含表达式,则仅将其添加到主查询中)。必需的参数也一样。

private function getDiscountPrice(int $weighting, Article $article, Customer $customer, array $args)
{
  // Early out if there's nothing to do.
  if (empty($args)) {
    return null;
  }

  $qb = Shopware()->Models()->createQueryBuilder()
    ->select('discount')
    ->from(PhaBase\Models\Discount::class,'discount')
  ;

  $conditions = $qb->expr()->andX();

  // Instead of setting each parameter individually (see below) you could set them 
  // all at once without the need for an ArrayCollection(), like you used, because your 
  // $args array is already in the correct format.
  // $qb->setParameters($args);

  foreach($args as $key => $arg) {
    $conditions->add('discount.'.$key.' = :'.$key);
    $qb->setParameter($key, $arg);
  }

  // You could check for $conditions->count() > 0 here, but we already did that at the beginning.
  try {
    return $this->calculateDiscountPrice(
      $article,
      $qb->where($conditions)->getQuery()->getOneOrNullResult(),
      $customer
    );
  } catch (NonUniqueResultException $e) {
    // @TODO Add log entry to inform about Exception
    return null;
 }
}

聚会晚了一点,但也许对别人有帮助。