在Doctrine结果集合中过滤的方法?

时间:2012-06-14 10:09:57

标签: doctrine-orm

我对Doctrine很新,所以对于那些经验丰富的人来说,这似乎是一个相当明显的问题。

我正在编写一个数据导入工具,必须检查每个导入的行包含有效数据。例如,Row有一个产品代码的引用,我需要检查是否存在具有该代码的预先存在的Product对象。如果不是,则将该行标记为无效。

现在我可以轻松地为每一行做这样的事情。

$productCode = $this->csv->getProductNumber();
$product = $doctrine->getRepository('MyBundle:Product')->findOneBy(array('code' => $productCode ));

但这似乎非常低效。所以我考虑返回整个产品系列,然后在其中进行迭代。

$query = $this->getEntityManager()->createQuery('SELECT p FROM MyBundle\Entity\Product p');
$products = $query->getResult();

一切都很好,但是我必须编写凌乱的循环来搜索。

两个问题:

1)。我想知道我是否缺少一些实用工具方法,例如你在Magento Collections中,你可以在收集结果中搜索,而不会产生额外的数据库命中。例如,在Magento中,这将迭代集合并过滤代码属性。

$collection->getItemByColumnValue("code","FZTY444");

2)。目前我正在使用下面的查询返回一个“矩形数组”。效率更高,但可能更好。

$query = $this->getEntityManager()->createQuery('SELECT p.code FROM MyBundle\Entity\Product p');
$products = $query->getResult();

有没有办法返回单维数组而不必重复结果集并转换成平面数组,所以我可以在结果上使用in_array()?

2 个答案:

答案 0 :(得分:6)

如果我正确理解你的问题,你想过滤getResult()返回的实体数组。我有一个类似的问题,我想我已经想出了两种方法。

方法1:数组

$products变量上使用array_filter方法。是的,这相当于后台的“循环”,但我认为这是一种普遍接受的过滤数组的方式,而不是自己编写。你需要提供一个回调(5.3首选的匿名函数)。这是一个例子

$codes = array_filter($products, function($i) {
    return $i->getCode() == '1234';
});

基本上在你的函数中,如果你希望结果返回到$codes则返回true,否则返回false(不确定false是否是必需的,或者void返回值是否足够)。

方法2:Doctrine的ArrayCollection

在自定义存储库中或者返回getResult()方法的位置,您可以返回一个ArrayCollection。这可以在Doctrine命名空间Doctrine\Common\Collections\中找到。可以在here找到关于此方法背后的界面的更多文档。所以在这种情况下你会有

$query = $this->getEntityManager()->createQuery('SELECT p FROM MyBundle\Entity\Product p');
$products = new ArrayCollection($query->getResult());

然后,您可以对数组集合使用filter()方法。以与array_filter非常相似的方式使用它。除了它不需要第一个参数,因为你这样称呼它:$products->filter(function($i) { ... });

ArrayCollection类是一个迭代器,因此您可以在foreach循环中将它用于您的内容,它与您的产品数组不应该有所不同。除非您的代码明确使用$products[$x],否则它应该是'n'play *。

*注意:我实际上没有测试过这个代码或概念,但基于我读过的所有内容似乎都是合法的。如果事实证明我错了,我会更新我的答案。

答案 1 :(得分:0)

您可以使用其他水合模式。 $ query-> getResult()通常返回对象水合作用的结果。看看$ query-> getScalarResult(),它应该更适合您的需求。

有关Doctrine 2 website的更多信息。