0

我有以下模型:

    class Word{

          ...........
/**
 * @ManyToOne(targetEntity="Language", cascade={"persist"})
 * @JoinColumn(name="language_id", referencedColumnName="id")
 */

protected $language;

   ..........................    

}

     class Language{
/**
 * @Id
 * @Column(type="integer", nullable=false)
 * @GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @Column(type="string", unique=true, nullable=false)
 */
protected $language;

 ........
}

我在数据库中有 3 种不同语言的 3 条记录。一种语言是独一无二的。

我无法创建一个新单词并将其链接到现有语言之一。即我想知道如何将Word的FK设置为​​语言的PK。而且由于模型中的 FK 不作为 int ID 存在,而是作为对象引用存在,所以我对如何实现它感到困惑。我尝试使用 Doctrine_Query::create()-> ... 但我也失败了。

我试过这个:

    $this->em = $this->doctrine->em;

    $w = $this->input->post('word');
    $d = $this->input->post('description');

    $desclan = $this->input->post('desclan'); //language is selected from a drop down 
                                              //list populated from the DB 
    $wordlan = $this->input->post('wordlan');

        $word = new Entity\Word;
        $description = new Entity\Description;
        $language = new Entity\Language;

        $language->setLanguage($wordlan);
        $language->setLanguageId($lanId); // assuming that $lanId is obtained from DB


        $word->setWord($w);
        $word->setLanguage($language);
        $description->setDescription($d);
        $word->setDescrp($description);

        $this->em->persist($word);
        $this->em->flush();

语言由下拉列表选择。这段代码当然会吐出该语言已经存在于数据库中。如何通过 Doctrine 代码简单地获取语言的 ID 并将其作为 FK language_id 放在数据库的“单词”表中?

先感谢您!

4

2 回答 2

0

那么今天我终于解决了......解决方案非常简单,我完全失明了。我显然没有正确考虑 Doctrine 的功能。

首先我尝试了这个:

    $this->em->getConnection()->executeQuery("Update word set language_id = ? where word = ?", array($this->langIds[$wordlan], $w));

为了将现有语言设置为单词,但这不是一个合适的解决方案,因为它违背了使用 ORM 的目的。今天,灯泡刚刚熄灭,我发现,既然学说保持你获得的对象和数据库之间的联系。例如:

    $word_check = $this->em->getRepository('Entity\Word')->findOneBy(array('word' => $w));

给我一个单词'where word = $w'。如果我只是修改这个词并调用 $em->flush(); 它将保存数据库中的差异。所以我只是想,如果我获得所需的语言对象并将其添加到新单词中,然后调用 $em->flush(); 它应该通过现有语言和新单词之间的 FK 在 DB 中创建连接,而不是创建新的语言对象并将其添加到单词中。尽管这个新对象具有相同的 id 和字符串单词,但它会将其视为新对象,并且学说试图将其作为新条目保存到语言表中,因此由于“唯一语言”的约束,它会吐出异常 I已设置。所以这段代码很简单:

    $new_w = new Entity\Word;

            $new_w->setWord($w);

            $lang = $this->em->getRepository('Entity\Language')->findOneBy(array('language' => $selected_language));

            $new_w->setLanguage($lang);                                

            $this->em->flush();

因此,这只是将现有语言添加到新创建的单词并正确设置 FK。如果您很难理解我在这篇文章中寻找的内容,我很抱歉,但是我希望现在已经解决了,有人可能会觉得它有帮助。

于 2013-11-08T16:03:45.603 回答
0

了解您在表单中发布的内容非常重要:

$desclan = $this->input->post('desclan'); //language is selected from a drop down 
                                              //list populated from the DB

你在这里说语言是从下拉列表中选择并从数据库中填充的,现在我问你表格中发布了什么?下拉列表可能会发布数据库中已存在的语言的 ID。您只需要找到正确的语言:

$languageFind = $entityManager->find('Entity\Language', $lanId); // $lanId is posted via form

然后将语言添加到单词中:

$word->setLanguage($languageFind);

PS:错误“语言已存在”是因为:

$language->setLanguageId($lanId); // assuming that $lanId is obtained from DB

您不能使用数据库中已存在的 $lanId 设置新 Language 类实例的LanguageId()。

于 2013-11-07T13:24:07.077 回答