4

私は Doctrine を初めて使用するので、これは経験豊富な人にとってはかなり明白な質問に思えるかもしれません。

インポートされるすべての行に有効なデータが含まれていることを確認する必要があるデータ インポート ツールを作成しています。たとえば、行に製品コードへの参照がある場合、そのコードを持つ既存の製品オブジェクトがあることを確認する必要があります。そうでない場合は、その行に無効のフラグを立てます。

これで、行ごとにこのようなことを簡単に行うことができます。

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

しかし、それは恐ろしく非効率的なようです。そこで、Product Collection 全体を返してから、その中で反復することを考えました。

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

すべて順調ですが、検索するために厄介なループを作成する必要があります。

2 つの質問:

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() を使用できますか?

4

2 に答える 2

7

あなたの質問を正しく理解できれば、getResult() によって返されるエンティティの配列をフィルタリングする必要があります。同様の質問がありましたが、それを行う2つの方法を見つけたと思います。

方法 1: 配列

変数でarray_filterメソッドを使用します$products。はい、これはバックグラウンドでの「ループ」に相当しますが、これは配列を自分で記述するのではなく、配列をフィルタリングする一般的に受け入れられる方法だと思います。コールバックを提供する必要があります (5.3 の匿名関数が推奨されます)。ここに例があります

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

基本的に関数では、結果を返す場合は true を返し、$codesそれ以外の場合は 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());

その後、配列コレクションで filter() メソッドを使用できます。array_filter と非常によく似た方法で使用します。次のように呼び出すため、最初の引数は必要ありません。$products->filter(function($i) { ... });

ArrayCollection クラスは反復子であるため、心ゆくforeachまでループで使用できます。また、製品の配列と実際に異なるものであってはなりません。コードで明示的に を使用しない限り、$products[$x]プラグ アンド プレイ* にする必要があります。

*注: このコードや概念を実際にテストしたことはありませんが、読んだすべての内容に基づいて、合法的なようです。間違っていることが判明した場合は、回答を更新します。

于 2012-11-13T16:16:24.437 に答える
0

別の水分補給モードを使用できます。$query->getResult() は通常、オブジェクトのハイドレーションで結果を返します。$query->getScalarResult() を見てください。これは、ニーズにより適しているはずです。

詳しくはDoctrine 2のウェブサイトをご覧ください。

于 2012-06-14T17:22:08.080 に答える