0

多くのアイテムを含む大きな XML ファイルを解析しています。各アイテムには多くのカテゴリがあり、繰り返すことができます。サンプル XML を次に示します。

<item>
    <category>Category1</category>
    <category>Category2</category>
    <category>Category3</category>
    <category>Category4</category>
    <category>Category5</category>
</item>
<item>
    <category>Category1</category>
    <category>Category2</category>
    <category>Category3</category>
    <category>Category7</category>
    <category>Category9</category>
</item>

doctrine を使用して上記の多対多の関係を処理すると、次のようなサンプル コードが作成されます。

$em = $this->getDoctrine()->getEntityManager();

foreach ($items as $item) {

    [...]

    $categories = ... //Array with category names, parsed from the XML.

    foreach ($categories as $category) {

        //This will check if the 'item' entity 
        //already has a category with that name.
        $exists = $entity->getCategories()->exists(function($key, $element) use ($category) {
            return $category == $element->getName();
        });

        if (!$exists) {

            //If there's already one on the database, we'll load it.
            //Otherwise, we'll save a new Category..
            $query = $this->_entityManager->createQueryBuilder();
            $query->select('c')
                  ->from("MyBundle:Category, 'c');
                  ->where("c.name = :name")
                  ->setParameter("name", $category);

            }

            $result = $query->getQuery()->getOneOrNullResult();

            if ($result != null) {
                $item->addCategory($result);
            } else {
                $categoryEntity = new Category($category);
                $em->persist($categoryEntity);
                $item->addCategory($categoryEntity);
            }

        }

    }

}

flush()問題は、すべてのアイテムのループを完了すると、entitymanagerだけになるということです。したがって、$query->getQuery()->getOneOrNullResult() 常に を返すため、null重複したカテゴリを作成することになります。

上記の XML の例では、次のようになります。

| item |
| 1    |
| 2    |

| category.id, category.name |
| 1,           Category1     |
| 2,           Category2     |
| 3,           Category3     |
| 4,           Category4     |
| 5,           Category5     |
| 6,           Category1     |
| 7,           Category2     |
| 8,           Category3     |
| 9,           Category7     |
| 10,          Category9     |

| item | category |
| 1    | 1        |
| 1    | 2        |
| 1    | 3        |
| 1    | 4        |
| 1    | 5        |
| 2    | 6        |
| 2    | 7        |
| 2    | 8        |
| 2    | 9        |
| 2    | 10       |

私は次のものが欲しかった:

| item |
| 1    |
| 2    |

| category.id, category.name |
| 1,           Category1     |
| 2,           Category2     |
| 3,           Category3     |
| 4,           Category4     |
| 5,           Category5     |
| 6,           Category7     |
| 7,           Category9     |

| item | category |
| 1    | 1        |
| 1    | 2        |
| 1    | 3        |
| 1    | 4        |
| 1    | 5        |
| 2    | 1        |
| 2    | 2        |
| 2    | 3        |
| 2    | 9        |
| 2    | 10       |

単に追加するだけ$em->flush()$em->persist($categoryEntity)解決しますが、まだフラッシュしたくありません (または、カテゴリのみをフラッシュします)。やるべきことがたくさんあり、取引を中断したくありません。必要に応じて、最初にロールバックし、未使用のカテゴリをすべて除外できるようにしたいと考えています (もちろん、追加のクエリを実行する必要はありません)。

私の質問は: データベースと教義の内部エンティティ マッピングの両方にアクセスして、ID を持っているかどうかにかかわらずエンティティを取得する方法はありますか? または、このマッピングを自分で作成し、DQL を実行してマッピングを確認する必要がありますか?

4

1 に答える 1