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

pow*_*boy 4 doctrine-orm

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

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

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

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

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

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

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

两个问题:

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

$collection->getItemByColumnValue("code","FZTY444");
Run Code Online (Sandbox Code Playgroud)

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

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

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

Mik*_*rko 6

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

方法1:数组

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

$codes = array_filter($products, function($i) {
    return $i->getCode() == '1234';
});
Run Code Online (Sandbox Code Playgroud)

基本上在你的函数中,如果你想要返回结果则返回$codestrue,否则返回false(不确定false是否是必需的,或者void返回值是否足够).

方法2:Doctrine的ArrayCollection

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

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

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

ArrayCollection类是一个迭代器,所以你可以在foreach循环中使用它来表达你的内容,它应该与你的产品数组完全不同.除非您的代码明确使用$products[$x],否则它应该是插件'播放*.

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


Pie*_*rre 0

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

更多信息请访问Doctrine 2 网站