2016-10-27 4 views
1

forループを使用して処理しているデータソースがあります。データソースに重複があることがあります。私はデータソースをループして「アイテム」エンティティを作成しています。私はそれらの重複を避けようとしていますが、アイテムはデータベースに送られていないので、重複チェック中に見つからないと思います。エンティティマネージャがフラッシュされる前に、forループで重複がないか確認してください。

はここでループのための私の擬似です:

foreach($datasource['data'] as $post){ 
    $dupe = $em->getRepository('AppBundle:Item')->findOneByDatasourceId($post['id']); 
    if(!$dupe){ 
     //process the item 
     $item = new Item(); 
     $item->setDatasourceId($post['id']); 
     $em->persist($item); 
    } 
} 

$em->flush(); 

これは、重複を見つけるん。

データがまだデータベースに送信されていない場合、重複を見つけるにはどうすればよいですか?私は、エンティティマネージャがまだプッシュされていないデータについて知っていたという印象を受けました。

ありがとう

+2

あなたはフラッシュが後にあなたが重複を持って続けば?もちろん、最適化された解決策ではありませんが、インラインIDをローカルの一時配列に格納し、この配列にもチェックインできます。 – Matteo

+0

@ Matteoのソリューションはパフォーマンスには最高だと思いますが、 'Item'エンティティで' UniqueEntity'制約を使用し、 'validator'サービスを使って' persist() 'の前に検証することができます。 – yceruto

答えて

1

EntityManager :: findは、永続化を待っているアイテムをチェックしません。アイテムは作業オブジェクトのユニットに格納され、理論上はチェックすることができます。しかし、それは少し痛みです。 @Matteoが示唆しているように、各永続化後にフラッシュすることもできますが、パフォーマンスに影響する可能性があります。

それはあなたのローカルキャッシュを所有するように十分に簡単です:

$datasourceCache = []; 
foreach($datasource['data'] as $post){ 
    $postId = $post['id']; 
    if (!isset($datasourceCache[$postID] (
     $datasourceCache[$postID] = true; 
     $dupe = $em->getRepository('AppBundle:Item')->findOneByDatasourceId($postId); 
     if(!$dupe){ 
      //process the item 
      $item = new Item(); 
      $item->setDatasourceId($postId); 
      $em->persist($item); 
     } 
    } 
} 
$em->flush(); 
関連する問題