2013-04-11 32 views
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> 

使用原則來處理上述的許多一對多的關係,我有一個示例代碼是這樣的:

$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->persist($categoryEntity)解決它$em->flush()後,但我不想刷新(或者就此而言,只需刷新一個類別)。有很多未完成的事情要做,我不想中斷我的交易。我想仍然能夠回滾到一開始,並排除所有未使用的類別,如果我需要(顯然,沒有運行其他查詢)。

我的問題是:有沒有一種方法來訪問數據庫和學說的內部實體映射來檢索一個實體,可能或可能沒有一個ID?或者我必須自己創建這個映射,運行一個DQL並檢查我的映射?

回答

1

Doctrine2不能爲你做這件事, 但很容易將新創建的類別存儲在你的循環中,並在你從數據庫中獲得MISS時檢查它們。

$_created_categories = array(); 

    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) { 
      $item->addCategory($result); 
     elseif (isset($_created_categories[$category])) { 
      $item->addCategory($_created_categories[$category]); 
     } else { 
      $categoryEntity = new Category($category); 
      $em->persist($categoryEntity); 
      $item->addCategory($categoryEntity); 

      $_created_categories[$category] = $categoryEntity; 
     } 
    } 

沒有內存開銷來存儲新的類別實體$_created_categories陣列中的所有目的通過參考PHP manipuled。

+0

我害怕我不能用教義來實現這一點。問題是:我的課程與我上面發佈的課程有所不同。它更通用,因爲它不應該只適用於項目和類別。它可能需要比簡單數組更強大的本地映射。我現在就開始着手。儘管非常感謝你的回答。 – 2013-04-11 17:08:24