抱歉,如果这个问题已经得到解答,我找不到任何答案。
我正在 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 表示存储翻译字符串的键/值。
目前我正在做的是:
从 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);
显示日志条目
我的问题是,如果键/值对尚不存在,我想创建一个翻译映射实体。但是,我不知道如何才能做到这一点,因为:
基本上,我想做的是为我的 TranslationMapping 实体获取一个管理器,它将管理数据库操作(如果需要,则获取和插入)并通过所有 Symfony 应用程序公开实体,主要是向存储库公开实体。
我已经尝试了几种解决方案,但没有选择,有人知道我如何实现这一目标吗?
谢谢。
基本上,您想要创建一个 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);