2

インポートされた製品データを繰り返し処理し、Doctrine2 を使用してデータベースに永続化するループがあります。

各製品について、その productID が既に存在するかどうかを確認します。その場合は、更新してください。そうでない場合は、作成して永続化します。

関連するエンティティについても同じことを行います。ここで問題が発生します。たとえば、各製品がメーカーに関連している場合です。各ループで、ManufacturerID が存在するかどうかを確認し、存在しない場合は作成/永続化します。1 回の反復で ManufacturerID=3 を作成し、その後、ManufacturerID3 の別の製品を作成した場合、Doctrine はまだフラッシュされていないため、それを認識していません。

ループが完了したときとは対照的に、ループごとに flush() を実行することでこれを修正できますが、より良い方法があるかどうか疑問に思っています.DoctrineがManufacturerID = 3のオブジェクトを検索する方法リポジトリと新しく永続化されたオブジェクトで?

すべてのループの後に Flush()ing が機能しますが、正しい方法とは思えません。

        $manufacturer = $this->em
            ->getRepository('AMyBundle:Manufacturer')
            ->findOneByPosId($item->manufacturerID);


        if (!$manufacturer)
        {
            $manufacturer = new Manufacturer();
            $manufacturer->setPosId($item->manufacturerID);
            $this->em->persist($manufacturer);
        }
4

2 に答える 2

1

「初期の最適化は諸悪の根源」D. クヌース

この単純な最適化を確認してください。より良いタイムが必要な場合は、袖を引き上げて降りてください。それ以外の場合は、先に進んでください。

テスト用に小さなベンチマークを追加しました。空のデータベースで両方のバリアントを確認することを忘れないでください。

$time1 = microtime(true);
// function start 

    if (!$manufacturer)
    {
        $manufacturer = new Manufacturer();
        $manufacturer->setPosId($item->manufacturerID);
        $this->em->persist($manufacturer);
        $this->em->flush(); // only flush when there's a new manufacturer
    }

// end of function
$time2 = microtime(true);
$time = $time2 - $time1;
printr("Time elapsed: $time");
于 2013-09-17T14:19:24.850 に答える
-2
Manufacturer m = new Manufacturer();
m.ManufacturerID = 123;
Database.Load(m);

m.Name = "abc";
Database.Store(m);

'much easier than symfony.  Sim.  Phony.  J/k.
于 2013-09-17T13:53:13.627 に答える