如何在Symfony2中拥有模型管理器?

问题描述 投票:0回答:1

抱歉,如果这个问题已经得到解答,我找不到任何答案。

我正在 Symfony2 中构建这个模型:

class LogEntry {
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime $log_timestamp
     *
     * @ORM\Column(name="log_timestamp", type="datetime")
     */
    private $log_timestamp;

    /**
     * @var TranslationMapping $source
     *
     * @ORM\ManyToOne(targetEntity="TranslationMapping", cascade={"persist"})
     * @ORM\JoinColumn(name="source", referencedColumnName="id")
     */
    private $source;

    /**
     * @var TranslationMapping $target
     *
     * @ORM\ManyToOne(targetEntity="TranslationMapping", cascade={"persist"})
     * @ORM\JoinColumn(name="target", referencedColumnName="id")
     */
    private $target;
...
}

使用这样的 TranslationMapping :

/**
 * LogAnalyzer\Bundle\CombatLogBundle\Entity\TranslationMapping
 *
 * @ORM\Table(name="TranslationMapping", uniqueConstraints={@ORM\UniqueConstraint(name="idValue_idx", columns={"stringId", "stringValue"})})
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 */
class TranslationMapping
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $stringId
     *
     * @ORM\Column(name="stringId", type="string", length=255)
     */
    private $stringId;

    /**
     * @var string $stringValue
     *
     * @ORM\Column(name="stringValue", type="string", length=255)
     */
    private $stringValue;


    /**
     * @ORM\PrePersist
     */
    public function beforePersist()
    {
        if ($this->stringId == null) {
            $this->stringId = "laGen_".time();
        }
    }

LogEntry 是基于通过正则表达式解析的字符串构建的。 TranslationMapping 表示存储翻译字符串的键/值。

目前我正在做的是:

  1. 检索字符串以构建 LogEntry
  2. 从 LogEntryRepository 中的字符串构建 LogEntry

    $logEntry = new LogEntry();
    $source = new TranslationMapping();
    if ($logEntry->getSourceIsPlayer()) {
        $source->setValueKey(str_replace("@", "", $matches["source"][0]));
    } else {
        $source->setValueKey($matches["source"][0], $matches["source_id"][0]);
        if (isset($matches["source_companion_name"][0])) { // It's a companion !
            $companion = new TranslationMapping();
            $companion->setValueKey($matches["source_companion_name"][0], $matches["source_companion_id"][0]);
            $logEntry->setSourceCompanion($companion);
            $source->setValueKey(str_replace("@", "", $matches["source"][0])); // And the source is the player's character name
        }
    }
    $logEntry->setSource($source);
    $logEntry->setTargetIsPlayer(strpos($matches["target"][0], "@") !== false);
    $target = new TranslationMapping();
    if ($logEntry->getTargetIsPlayer()) {
        $target->setValueKey(str_replace("@", "", $matches["target"][0]));
    } else {
        $target->setValueKey($matches["target"][0], $matches["target_id"][0]);
        if (isset($matches["target_companion_name"][0])) { // It's a companion !
            $companion = new TranslationMapping();
            $companion->setValueKey($matches["target_companion_name"][0], $matches["target_companion_id"][0]);
            $logEntry->setTargetCompanion($companion);
            $target->setValueKey(str_replace("@", "", $matches["target"][0])); // And the target is the player's character name
        }
    }
    $logEntry->setTarget($target);
    
  3. 显示日志条目

我的问题是,如果键/值对尚不存在,我想创建一个翻译映射实体。但是,我不知道如何才能做到这一点,因为:

  • 我无法从另一个存储库访问 TranslationMappingRepository
  • 我无法从存储库访问服务
  • 我无法通过 Doctrine2 使用 INSERT ... ON DUPLICATE KEY UPDATE 查询

基本上,我想做的是为我的 TranslationMapping 实体获取一个管理器,它将管理数据库操作(如果需要,则获取和插入)并通过所有 Symfony 应用程序公开实体,主要是向存储库公开实体。

我已经尝试了几种解决方案,但没有选择,有人知道我如何实现这一目标吗?

谢谢。

php symfony design-patterns doctrine-orm entitymanager
1个回答
5
投票

基本上,您想要创建一个 S2 服务并将实体管理器注入其中。 手册中有很多示例,但如果您确实需要,我可以发布一个示例。

存储库在处理一种实体类型时非常有用,但正如您发现的那样,在处理多种类型时存储库就没那么有用了。 我很少再用它们了。 只需将功能包装在服务中即可。

不幸的是,INSERT ... ON DUPLICATE KEY UPDATE 不是标准 sql,因此 Doctrine 不支持,尽管您可以将其添加为自定义函数。 但最好的办法是检查密钥是否存在,然后进行相应调整。 确保捕获任何异常以防万一。

我并没有真正详细地浏览你的代码,但 S2 确实有很多翻译内容。 其中一些可能也有帮助。

更新:

有关创建服务的信息可以在这里找到: http://symfony.com/doc/current/book/service_container.html

在你的 services.xml 文件中,你可能有类似的内容:

<service 
    id="zayso.core.project.manager"        
    class="Zayso\ZaysoBundle\Component\Manager\ProjectManager" public="true">
        <argument type="service" id="doctrine.orm.entity_manager" />
</service>

你的经理会有一个像这样的 __construct:

class ProjectManager
{
    protected $em = null;

    public function getEntityManager() { return $this->em; }

    public function __construct($em) { $this->em = $em; }

然后在你的控制器中你会做类似的事情:

$manager = $this->get(zayso.core.project.manager);
$manager->newLogEntry($params);
© www.soinside.com 2019 - 2024. All rights reserved.