1

好的,这是解决树木问题的真正木材。

我正在尝试使一对多对多一的实体结构正常工作。我有三个实体

  • 项目(有 ID 和名称)
  • 研究员(有 ID 和姓名)
  • 项目研究员(有 ID、项目 ID、研究员 ID 和研究员在该项目中的角色)

所以它们编码如下(使用注释)

namespace ons\Bundle\Geneapro\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * Project
 *
 * @ORM\Table(name="gpt_project")
 * @ORM\Entity
 */
class Project
{
    /**
     * @var string
     *
     * @ORM\Column(name="Name", type="string", nullable=false)
     */
    private $name;

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

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity=" ResearcherProject", mappedBy="project")
     */
    private $researcherprojects;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->researcherprojects = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Project
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

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

    /**
     * Add researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     * @return Project
     */
    public function addResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects[] = $researcherprojects;
        return $this;
    }

    /**
     * Remove researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     */
    public function removeResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects->removeElement($researcherprojects);
    }

    /**
     * Get researcherprojects
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getResearcherprojects()
    {
        return $this->researcherprojects;
    }
}

研究员几乎相同

namespace ons\Bundle\Geneapro\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * Researcher
 *
 * @ORM\Table(name="gpt_researcher")
 * @ORM\Entity
 */
class Researcher
{
    /**
     * @var string
     *
     * @ORM\Column(name="Name", type="string", nullable=false)
     */
    private $name;

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

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity=" ResearcherProject", mappedBy="researcher")
     */
    private $researcherprojects;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->researcherprojects = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Researcher
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

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

    /**
     * Add researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     * @return Researcher
     */
    public function addResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects[] = $researcherprojects;
        return $this;
    }

    /**
     * Remove researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     */
    public function removeResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects->removeElement($researcherprojects);
    }

    /**
     * Get researcherprojects
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getResearcherprojects()
    {
        return $this->researcherprojects;
    }
}

最后是 ResearcherProject

namespace ons\Bundle\Geneapro\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * ResearcherProject
 *
 * @ORM\Table(name="gpt_researcher_project")
 * @ORM\Entity
 */
class ResearcherProject
{
    /**
     * @var string
     *
     * @ORM\Column(name="Role", type="string", nullable=false)
     */
    private $role;

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

    /**
     * @var Researcher
     *
     * @ORM\ManyToOne(targetEntity="Researcher", inversedBy="researcherprojects")
     */
    private $researcher;

    /**
     * @var Project
     *
     * @ORM\ManyToOne(targetEntity="Project", inversedBy="researcherprojects")
     */
    private $project;

    /**
     * Set role
     *
     * @param string $role
     * @return ResearcherProject
     */
    public function setRole($role)
    {
        $this->role = $role;
        return $this;
    }

    /**
     * Get role
     *
     * @return string 
     */
    public function getRole()
    {
        return $this->role;
    }

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

    /**
     * Set researcher
     *
     * @param Researcher $researcher
     * @return ResearcherProject
     */
    public function setResearcher(Researcher $researcher = null)
    {
        $this->researcher = $researcher;
        return $this;
    }

    /**
     * Get researcher
     *
     * @return Researcher 
     */
    public function getResearcher()
    {
        return $this->researcher;
    }

    /**
     * Set project
     *
     * @param Project $project
     * @return ResearcherProject
     */
    public function setProject(Project $project = null)
    {
        $this->project = $project;
        return $this;
    }

    /**
     * Get project
     *
     * @return Project 
     */
    public function getProject()
    {
        return $this->project;
    }
}

不出所料,这会产生以下 SQL

CREATE TABLE gpt_project (id INT AUTO_INCREMENT NOT NULL, Name VARCHAR(255) NOT NULL, Description VARCHAR(255) DEFAULT NULL, ClientData LONGTEXT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

CREATE TABLE gpt_researcher (id INT AUTO_INCREMENT NOT NULL, Name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

CREATE TABLE gpt_researcher_project (id INT AUTO_INCREMENT NOT NULL, researcher_id INT DEFAULT NULL, project_id INT DEFAULT NULL, Role VARCHAR(255) NOT NULL, INDEX IDX_5E15A9AEC7533BDE (researcher_id), INDEX IDX_5E15A9AE166D1F9C (project_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

ALTER TABLE gpt_researcher_project ADD CONSTRAINT FK_5E15A9AEC7533BDE FOREIGN KEY (researcher_id) REFERENCES gpt_researcher (id);

ALTER TABLE gpt_researcher_project ADD CONSTRAINT FK_5E15A9AE166D1F9C FOREIGN KEY (project_id) REFERENCES gpt_project (id);

到目前为止一切顺利,我现在正在使用 Behat 来编写我的场景,并且我定义了以下功能。

Feature: ResearcherProject
  In order to track who did research
  As the Data Bundle
  I need to be able to create and manage ResearcherProjects

Background:
    Given there is no "ResearcherProject" in database
    And there is no "Project" in database
    And there is no "Researcher" in database

Scenario: A ResearcherProject joins Researchers to Projects
    When I create a Project "New Project"  
    And I create a Researcher "Researcher" 
    And I add Researcher "Researcher" to Project "New Project" as "Lead"    
    Then Researcher Project "1" joins "Researcher" to Project "New Project" as "Lead"    
    And Project "New Project" is Researched By "1" Researcher 
    And Researcher "Researcher" Researches "1" Project

数据很好地加载到数据库中,并且将项目链接到角色中的研究人员的研究人员项目的测试有效,但随后发生以下情况

01. Failed asserting that actual size 0 matches expected size 1. 
    In step `And Project "New Project" is Researched By "1" Researcher'.

进行测试的两个函数是

/**
 * @Then /^Researcher Project "([^"]*)" joins "([^"]*)" to Project "([^"]*)" as "([^"]*)"$/
 */
public function researcherProjectJoinsToProjectAs($ResearcherProjectID, $ResearcherName, $ProjectName, $Role)
{
    $rp=$this->getEntityByID("ResearcherProject", $ResearcherProjectID);
    assertEquals($ResearcherProjectID, $rp->getID());
    assertEquals($ResearcherName,$rp->getResearcher()->getName());
    assertEquals($ProjectName,$rp->getProject()->getName());                
    assertEquals($Role,$rp->getRole());
}

/**
 * @Then /^Project "([^"]*)" is Researched By "([^"]*)" Researcher$/
 */
public function projectIsResearchedByResearcher($ProjectName, $expectedCount)
{        
    $project=$this->getEntityByName("Project", $ProjectName);
    assertCount($expectedCount*1, $project->getResearcherprojects());
}

GetEntityByNameGetEntityByID按照他们所说的去做。

我做错了什么,为什么我可以从内向外工作,但不能从外向内工作?这已经困扰我两天了,所以欢迎任何帮助,我相信这真的很简单,但它超出了我的范围。

编辑

所以我想我可以开始看到树了,但是现在这是一个稍微不同的问题!这应该是一个无头包,所以我没有提供任何视图或控制器。添加树枝模板并运行它会弹出链接。

所以它必须是导致它的测试中的行为。

4

2 回答 2

0
assertEquals($expectedCount*1, $project->getResearcherprojects());

$project->getResearcherprojects()将返回一个 ArrayCollection ResearcherProject。如果你想计算它们,你必须这样做:

assertEquals($expectedCount*1, $project->getResearcherprojects()->count());
于 2013-08-14T16:56:52.753 回答
0

好的,

让树枝方法起作用后,我想知道如果我只是从数据库中提取它是否会起作用,所以我将场景更改为

Feature: ResearcherProject
  In order to track who did research
  As the Data Bundle
  I need to be able to create and manage Researchers


Scenario: A ResearcherProject joins Researchers to Projects
    Then Researcher Project "1" joins "Researcher" to Project "New Project" as "Lead"    
    And Project "New Project" is Researched By "1" Researcher 
    And Researcher "Researcher" Researches "1" Project 

并且宾果游戏都通过了,所以它看起来像是一个缓存问题。实体管理器显然正在返回它捕获的我的项目和研究人员的版本,它们还没有更新

所以问题就在这里...

/**
 * @Given /^I add Researcher "([^"]*)" to Project "([^"]*)" as "([^"]*)"$/
 */
public function iAddResearcherToProjectAs($ResearcherName, $ProjectName, $Role)
{

    $em = $this->getEntityManager();


    //Get Researcher
    $researcher=$em->getRepository('onsGeneaproDataBundle:Researcher')
                   ->findOneByName($ResearcherName);
    //Get Project
    $project=$em->getRepository('onsGeneaproDataBundle:Project')
                ->findOneByName($ProjectName);

    $researcherproject = new \ons\Bundle\Geneapro\DataBundle\Entity\ResearcherProject();
    $researcherproject->setRole($Role);
    $researcherproject->setProject($project);        
    $researcherproject->setResearcher($researcher);

//*** The following Two Lines make it work ***//
    $project->addResearcherproject($researcherproject);//Why dose this not happen automaticaly?
    $researcher->addResearcherproject($researcherproject);//Why dose this not happen automaticaly?
//*** ***//

    $em->persist($researcherproject);
    $em->flush();
}

如果我进行反向更新并将 ResearcherProject 添加到 Researcher 和 Project 中,那么所有测试都会通过。

但这引出了以下问题

  1. 为什么项目和研究员不接收更新?
  2. 或如何在更新实体后强制实体管理器清除其缓存。
于 2013-08-14T17:04:26.440 回答