在Doctrine中建立多种关系

时间:2014-05-21 03:51:12

标签: php orm doctrine-orm

我有一个属性:

(注意:legacy_id不是我正在做的,现在已经在应用程序中根深蒂固,所以此时无法更改)

<?php

namespace Entity\Beaverusiv;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Entity\Beaverusiv\Property
 *
 * @ORM\Entity()
 * @ORM\Table(name="properties", indexes={@ORM\Index(name="fk_properties_smoking_options1_idx", columns={"smoking_id"}), @ORM\Index(name="fk_properties_linen_options1_idx", columns={"linen_id"}), @ORM\Index(name="fk_properties_pets_options1_idx", columns={"pets_id"}), @ORM\Index(name="fk_properties_property_city1_idx", columns={"city_id"})})
 */
class Property
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="integer")
     */
    protected $legacy_id;

    /**
     * @ORM\ManyToMany(targetEntity="FeaturesOption", mappedBy="properties")
     */
    protected $featuresOptions;

    public function __construct()
    {
        $this->featuresOptions = new ArrayCollection();
    }

    /**
     * Set the value of id.
     *
     * @param integer $id
     * @return \Entity\Beaverusiv\Property
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get the value of id.
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set the value of legacy_id.
     *
     * @param integer $legacy_id
     * @return \Entity\Beaverusiv\Property
     */
    public function setLegacyId($legacy_id)
    {
        $this->legacy_id = $legacy_id;

        return $this;
    }

    /**
     * Get the value of legacy_id.
     *
     * @return integer
     */
    public function getLegacyId()
    {
        return $this->legacy_id;
    }

    /**
     * Add FeaturesOption entity to collection.
     *
     * @param \Entity\Beaverusiv\FeaturesOption $featuresOption
     * @return \Entity\Beaverusiv\Property
     */
    public function addFeaturesOption(FeaturesOption $featuresOption)
    {
        $this->featuresOptions[] = $featuresOption;

        return $this;
    }

    /**
     * Get FeaturesOption entity collection.
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getFeaturesOptions()
    {
        return $this->featuresOptions;
    }
}

和FeaturesOption:

<?php

namespace Entity\Beaverusiv;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Entity\Beaverusiv\FeaturesOption
 *
 * @ORM\Entity()
 * @ORM\Table(name="features_options")
 */
class FeaturesOption
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    protected $display_order;

    /**
     * @ORM\Column(type="string", length=200, nullable=true)
     */
    protected $text;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    protected $status;

    /**
     * @ORM\ManyToMany(targetEntity="Property", inversedBy="featuresOptions")
     * @ORM\JoinTable(name="properties_features",
     *     joinColumns={@ORM\JoinColumn(name="feature_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="property_id", referencedColumnName="id")}
     * )
     */
    protected $properties;

    public function __construct()
    {
        $this->properties = new ArrayCollection();
    }

    /**
     * Set the value of id.
     *
     * @param integer $id
     * @return \Entity\Beaverusiv\FeaturesOption
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get the value of id.
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set the value of display_order.
     *
     * @param integer $display_order
     * @return \Entity\Beaverusiv\FeaturesOption
     */
    public function setDisplayOrder($display_order)
    {
        $this->display_order = $display_order;

        return $this;
    }

    /**
     * Get the value of display_order.
     *
     * @return integer
     */
    public function getDisplayOrder()
    {
        return $this->display_order;
    }

    /**
     * Set the value of text.
     *
     * @param string $text
     * @return \Entity\Beaverusiv\FeaturesOption
     */
    public function setText($text)
    {
        $this->text = $text;

        return $this;
    }

    /**
     * Get the value of text.
     *
     * @return string
     */
    public function getText()
    {
        return $this->text;
    }

    /**
     * Set the value of status.
     *
     * @param integer $status
     * @return \Entity\Beaverusiv\FeaturesOption
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get the value of status.
     *
     * @return integer
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Add Property entity to collection.
     *
     * @param \Entity\Beaverusiv\Property $property
     * @return \Entity\Beaverusiv\FeaturesOption
     */
    public function addProperty(Property $property)
    {
        $property->addFeaturesOption($this);
        $this->properties[] = $property;

        return $this;
    }

    /**
     * Get Property entity collection.
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getProperties()
    {
        return $this->properties;
    }
}

枢轴:

<?php

namespace Entity\Beaverusiv;

use Doctrine\ORM\Mapping as ORM;

/**
 * Entity\Beaverusiv\PropertiesFeature
 *
 * @ORM\Entity()
 * @ORM\Table(name="properties_features", indexes={@ORM\Index(name="fk_properties_features_features_options1_idx", columns={"feature_id"}), @ORM\Index(name="fk_properties_features_properties1_idx", columns={"property_id"})})
 */
class PropertiesFeature
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    protected $feature_id;

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    protected $property_id;

    /**
     * @ORM\ManyToOne(targetEntity="FeaturesOption", inversedBy="propertiesFeatures")
     * @ORM\JoinColumn(name="feature_id", referencedColumnName="id", nullable=false)
     */
    protected $featuresOption;

    /**
     * @ORM\ManyToOne(targetEntity="Property", inversedBy="propertiesFeatures")
     * @ORM\JoinColumn(name="property_id", referencedColumnName="id", nullable=false)
     */
    protected $property;

    public function __construct()
    {
    }

    /**
     * Set the value of feature_id.
     *
     * @param integer $feature_id
     * @return \Entity\Beaverusiv\PropertiesFeature
     */
    public function setFeatureId($feature_id)
    {
        $this->feature_id = $feature_id;

        return $this;
    }

    /**
     * Get the value of feature_id.
     *
     * @return integer
     */
    public function getFeatureId()
    {
        return $this->feature_id;
    }

    /**
     * Set the value of property_id.
     *
     * @param integer $property_id
     * @return \Entity\Beaverusiv\PropertiesFeature
     */
    public function setPropertyId($property_id)
    {
        $this->property_id = $property_id;

        return $this;
    }

    /**
     * Get the value of property_id.
     *
     * @return integer
     */
    public function getPropertyId()
    {
        return $this->property_id;
    }

    /**
     * Set FeaturesOption entity (many to one).
     *
     * @param \Entity\Beaverusiv\FeaturesOption $featuresOption
     * @return \Entity\Beaverusiv\PropertiesFeature
     */
    public function setFeaturesOption(FeaturesOption $featuresOption = null)
    {
        $this->featuresOption = $featuresOption;
        $this->feature_id = $featuresOption->getId();

        return $this;
    }

    /**
     * Get FeaturesOption entity (many to one).
     *
     * @return \Entity\Beaverusiv\FeaturesOption
     */
    public function getFeaturesOption()
    {
        return $this->featuresOption;
    }

    /**
     * Set Property entity (many to one).
     *
     * @param \Entity\Beaverusiv\Property $property
     * @return \Entity\Beaverusiv\PropertiesFeature
     */
    public function setProperty(Property $property = null)
    {
        $this->property = $property;
        $this->property_id = $property->getLegacyId();

        return $this;
    }

    /**
     * Get Property entity (many to one).
     *
     * @return \Entity\Beaverusiv\Property
     */
    public function getProperty()
    {
        return $this->property;
    }
}

我不得不从旧数据库中引入数据,如下所示:

<?php
public function sync()
{

    $persist_count = 0; // Keep track of home many properties are ready to be flushed
    $flush_count = 20; // Persist and flush the properties in groups of...

    $i = 0;

    $CI =& get_instance();

    $legacy_properties = null;

    while ($legacy_properties !== false)
    {
        $legacy_properties = $this->doctrine->mssql
            ->getRepository('Entity\MSSQL\TblProperty')
            ->getProperties($i, $flush_count);

        if (count($legacy_properties)===0)
        {
            break;
        }


        foreach ($legacy_properties as $legacy_property)
        {
            // Legacy ID
            $legacy_id = $legacy_property['propertyID'];

            // Lets see if this property already exists in the new database. If it does, we'll just use that.
            $property    = $this->doctrine->em
                                ->getRepository('Entity\Beaverusiv\Property')
                                ->findOneBy(array(
                                    'legacy_id' => $legacy_id
                                ));

            // If the property from the legacy database does not exist in the new database, let's add it.
            if (! $property)
            {
                $property = new Entity\Beaverusiv\Property; // create a new property instance
                $property->setLegacyId($legacy_id);
            }

            // Update property details
            // Set all the other Property fields

            $legacy_features = $this->doctrine->mssql
                ->getRepository('Entity\MSSQL\TblProperty')
                ->findOneBy(array('propertyID' => $legacy_id))
                ->getTblPropertyFeaturesJoins();

            foreach ($legacy_features as $legacy_feature) {
                $feature_id = $legacy_feature->getTblPropertyFeature()->getFeatureID();
                $feature = $this->doctrine->em
                                ->getRepository('Entity\Beaverusiv\FeaturesOption')
                                ->findOneBy(array(
                                    'id' => $feature_id
                                ));

                $feature_pivot = new Entity\Beaverusiv\PropertiesFeature;
                $feature_pivot->setFeaturesOption($feature);
                $feature_pivot->setProperty($property);
                $this->doctrine->em->merge($feature_pivot);
            }

            // Persist this property, ready forz flushing in groups of $persist_bunch
            $this->doctrine->em->persist($property);
            $persist_count++;

            // If the number of properties ready to be flushed is the number set in $flush_count, lets flush these properties
            if ($persist_count == $flush_count) {
                $this->doctrine->em->flush();
                $this->doctrine->em->clear();
                $this->doctrine->mssql->clear();
            }
        }

        // Flush any remaining properties
        $this->doctrine->em->flush();

        $i += $flush_count;
    }
}

显然这是错误的,但我无法在任何地方找到一个适当的例子。目前它由于某种原因而耗尽内存并抱怨数据透视表中的重复项。如何设置正确的关系,以便我不参考数据透视表,而是直接将FeatureOption添加到Property

1 个答案:

答案 0 :(得分:0)

好的,通过更改属性来设法让它工作:

/**
 * @ORM\ManyToMany(targetEntity="FeaturesOption", mappedBy="properties")
 */
protected $featuresOptions;

到此:

/**
 * @ORM\ManyToMany(targetEntity="FeaturesOption")
 * @ORM\JoinTable(name="properties_features",
 *     joinColumns={@ORM\JoinColumn(name="property_id", referencedColumnName="legacy_id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="feature_id", referencedColumnName="id")}
 * )
 */
protected $featuresOptions;

删除数据透视表实体,并删除FeaturesOption实体中的反向引用内容。