我尝试使用Doctrine2 Mapping,但是经过8小时的问题后,我真的需要你的帮助。
我有3个PostgreSQL
表,第一个是房子
Column | Type | Modifiers
---------+----------------+----------------------------------------------------
id | integer | not null default nextval('house_id_seq'::regclass)
name | character(255) | not null
address | character(255) |
rooms | integer | not null
Indexes:
"house_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "room" CONSTRAINT "room_house_id_fkey" FOREIGN KEY (house_id) REFERENCES house(id) ON UPDATE CASCADE ON DELETE CASCADE
,第二个是
Table "public.room"
Column | Type | Modifiers
-----------+------------------------+---------------------------------------------------
id | integer | not null default nextval('room_id_seq'::regclass)
name | character varying(255) |
room_type | integer |
vacant | boolean |
house_id | integer |
Indexes:
"room_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"room_house_id_fkey" FOREIGN KEY (house_id) REFERENCES house(id) ON UPDATE CASCADE ON DELETE CASCADE
,最后一个是
Table "public.category"
Column | Type | Modifiers
------------+----------------+-------------------------------------------------------
id | integer | not null default nextval('category_id_seq'::regclass)
name | character(255) | not null
min_person | integer | not null
max_person | integer | not null
Indexes:
"category_pkey" PRIMARY KEY, btree (id)
我在room_house_id上插入了一个引用House表上的house.id的FK。
在我的Zend Framework2中,我的实体声明为
namespace Structures\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Structures\Entity\House
*
* @ORM\Table(name="house")
* @ORM\Entity(repositoryClass="Structures\Entity\Repository\HouseRepository")
*/
class House
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="house_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* @var string $address
*
* @ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* @var string $rooms
*
* @ORM\Column(name="rooms", type="integer", nullable=false)
*/
private $rooms;
/**
*
* @ORM\OneToMany(targetEntity="Structures\Entity\Room", mappedBy="house", cascade={"remove", "persist"})
*/
protected $house_room;
}
/**
* Structures\Entity\Room
*
* @ORM\Table(name="room")
* @ORM\Entity(repositoryClass="Structures\Entity\Repository\RoomRepository")
*/
class Room {
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Id
*/
private $id;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255,nullable=false)
*/
private $name;
/**
* @var boolean $vacant
*
* @ORM\Column(name="vacant", type="boolean", nullable=false)
*/
private $vacant;
/**
* @var Structures\Entity\Category
*
* @ORM\ManyToOne(targetEntity="Structures\Entity\Category" , cascade={"persist", "remove"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="room_type", referencedColumnName="id")
* })
*/
private $category;
/**
* @ORM\ManyToOne(targetEntity="Structures\Entity\House", inversedBy="house_room", cascade={"remove", "persist"})
*
*/
private $house;
}
/**
* Structures\Entity\Category
*
* @ORM\Table(name="category")
* @ORM\Entity(repositoryClass="Structures\Entity\Repository\CategoryRepository")
*
*/
class Category {
/**
* @var integer $id
*
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Id
*
*/
private $id;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*
*/
private $name;
/**
* @var integer $min_person
* @ORM\Column(name="min_person", type="integer" , nullable=false)
*/
private $min_person;
/**
* @var integer $max_person
* @ORM\Column(name="max_person", type="integer", nullable=false)
*/
private $max_person;
}
与房间和类别的关系也起作用。
一个关注的房间和房子表根本不起作用。我无法成功将FK house_id
映射到House表上的id列。所有编辑/保存操作均失败,house_id
始终设置为NULL
。
请让我明白我犯错的地方,我疯了
更新:
我试图改变House和Room之间的关系。 我删除了House的OneToMany并更改了
中的ManyToOne/**
* @var Structure\Entity\Structure
*
* @ORM\ManyToOne(targetEntity="Structures\Entity\House")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="house_id", referencedColumnName="id", nullable=FALSE)
* })
*/
private $house;
当我用
取回房间时$room = $this->roomService->getRoom($id);
var_dump($room);
我有
object(Structures\Entity\Room)#383 (4)
{
["id":"Structures\Entity\Room":private]=> int(77)
["name":"Structures\Entity\Room":private]=> string(33) "my room"
["structure":"Structures\Entity\Room":private]=> object(Structures\Entity\House)#339 (4) {
["id":"Structures\Entity\House":private]=> int(3)
["name":"Structures\Entity\House":private]=> string(255) "hotel2b "
["address":"Structures\Entity\House":private]=> string(255) "hotel2b avenue"
["number_of_rooms":"Structures\Entity\House":private]=> int(20) }
["house_id":"Structures\Entity\Room":private]=> int(3)
}
如果我使用OneToMany关系,var_dump($ room)会返回一整页,我不知道这意味着什么转储!
但是,编辑房间时,列house_is总是设置为NULL。 仍在努力
更新:3月9日
花了几个小时阅读教程后,我从头开始编写所有内容。 House Entity不再退出。结构实体是新的实体。 我的问题:使用Doctrine2添加和编辑OneToMany和ManyToOne关系的数据。
我的解决方案:
我的实体是 namespace Structures \ Entity;
将Doctrine \ ORM \ Mapping用作ORM;
/**
* Structures\Entity\Structure
*
* @ORM\Table(name="room")
* @ORM\Entity(repositoryClass="Structures\Entity\Repository\RoomRepository")
*/
class Room {
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Id
*/
private $id;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255,nullable=false)
*
*/
private $name;
/**
* @var integer structure_id
* @ORM\Column(name="structure_id", type="integer", nullable=false)
*/
private $structure_id;
/**
* @var Structure\Entity\Structure
*
* @ORM\ManyToOne(targetEntity="Structure", inversedBy="rooms")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="structure_id", referencedColumnName="id")
* })
*/
private $structure;
public function __construct()
{
// $this->structure = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @param $data
*/
public function exchangeArray($data)
{
$this->fillWith($data);
}
/**
* @param $data
* @return Room
*/
public static function createFromArray($data)
{
$room = new Room();
$room->fillWith($data);
return $room;
}
public function updateFromArray($room)
{
$structure_id = $room->getStructureId();
$structure = $this->getStructure($structure_id);
$room->setStructure($structure);
return $room;
}
/**
* Sets id
* @param $i_id
*/
private function set_Id($i_id) {
$this->id = $i_id;
}
/**
* Gets id
* @return integer
*
*/
public function getId() {
return $this->id;
}
/**
* Set name
* @param string name
*
*/
public function setName($name) {
$this->name = $name;
}
/**
* Get name
* @return string
*
*/
public function getName() {
return $this->name;
}
public function getStructureId()
{
return $this->structure_id;
}
/**
*
* @return \Doctrine\Common\Collections\ArrayCollection|Structure\Entity\Structure
*/
public function getStructure() {
return $this->structure;
}
public function setStructure($structure) {
$this->structure = $structure;
}
和结构
namespace Structures\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Structures\Entity\Structure
*
* @ORM\Table(name="structure")
* @ORM\Entity(repositoryClass="Structures\Entity\Repository\StructureRepository")
*/
class Structure {
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="structure_id_seq", allocationSize=1, initialValue=1)
*
*/
private $id;
/**
* @var string address
*
* @ORM\Column(name="name", type="string", length=255,nullable=false)
*/
private $name;
/**
* @var string address
*
* @ORM\Column(name="address", type="string", length=255,nullable=false)
*
*/
private $address;
/**
* @var integer $rooms
*
* @ORM\Column(name="number_of_rooms", type="integer", nullable=false)
*/
private $number_of_rooms;
/**
* @ORM\OneToMany(targetEntity="Room", mappedBy="structure")
*/
private $rooms;
public function __construct() {
$this->rooms = new \Doctrine\Common\Collections\ArrayCollection();
}
public function exchangeArray($data) {
$this->fillWith($data);
}
public static function createFromArray($data)
{
$structure = new Structure();
$structure->fillWith($data);
return $structure;
}
private function set_Id($i_id) {
$this->id = $i_id;
}
/**
* Get id
* @return integer
*
*/
public function getId() {
return $this->id;
}
/**
* Set name
* @param string name
*
*/
public function setName($name) {
$this->name = $name;
}
/**
* Get name
* @return string
*
*/
public function getName() {
return $this->name;
}
/**
* Set address
* @param string address
*
*/
public function setAddress($address) {
$this->address = $address;
}
/**
* Get address
* @return string
*
*/
public function getAddress() {
return $this->address;
}
/**
* Set rooms
* @params integer rooms
*
*/
public function setRoom($room) {
$this->rooms = $room;
}
/**
* Get rooms
* @return integer
*
*/
public function getRoom() {
return $this->rooms;
}
/**
* @param $rooms
*/
public function setNumberOfRooms($number_of_rooms) {
$this->number_of_rooms = $number_of_rooms;
}
/**
* @return int
*/
public function getNumberOfRooms() {
return $this->number_of_rooms;
}
当我创建一个新房间时,我调用一个函数来处理我的Zend \ Form \ Form数据
public function processForm() {
if ($this->request->isPost()) {
// get the post data
$post = $this->request->getPost()->toArray();
// fill form
$this->form->setData($post);
// check if form is valid
if (!$this->form->isValid()) {
//prepare view
$view = new ViewModel(array('form' => $this->form,
'title' => 'Process Form :
Some errors during rooms processing'));
$view->setTemplate('structures/rooms/create');
return $view;
}
/* here I set the structure's Id from $structure obj gets from
$this->params('id')
*/
$structure = $this->getStructureFromQuerystring();
$post['structure_id'] = $structure->getId();
/* here I call a service method to create a Room instance and fills it
with data from $this->form
*/
$return = $this->roomService->insertRoomFromArray($post);
if ($return ) {
$this->flashMessenger()->setNamespace('rooms')->addMessage
('Operation executed correctly');
return $this->redirect()->toRoute('rooms/index');
}
}
服务方法
public function insertRoomFromArray(array $am_formData) {
/* here I get the structure with the id stores in $am_formData*/
$structure = $this->getStructure($am_formData['structure_id']);
/* here I copy the $structure obj in $am_formData array */
$am_formData['structure'] = $structure;
/* here I call the Room Entity method createFromArray to create the Room */
$I_event = Room::createFromArray($am_formData);
/* here I call the mapper method to persist data */
$this->I_mapper->saveRoom($I_event);
return $I_event;
}
房间实体
public static function createFromArray($data)
{
/* create new Room obj */
$room = new Room();
/* fill with data */
$room->fillWith($data);
return $room;
}
public function fillWith($data) {
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->name = (isset($data['name'])) ? $data['name'] : null;
/* here I copy the structure obj for relationship */
$this->structure = (isset($data['structure'])) ? $data['structure'] : null;
}
Mapper实体 公共功能saveRoom(\ Structures \ Entity \ Room $ room) {
$this->entityManager->persist($room);
$this->entityManager->flush();
}
它有效并且新房间具有正确结构的id集。
什么时候我需要编辑房间?我的解决方案
来自控制器
public function editAction() {
/* Gets the room obj by $this->params('id') */
$room = $this->getRoomFromQueryString();
$this->form->bind($room);
$view = $this->processEditForm($room);
if (!$view instanceof ViewModel) {
$view = new ViewModel(array('form' => $this->form,
'title' => 'Edit Room: ' . $room->getName() ,
'structure' => $room->getStructure()));
$view->setTemplate('structures/rooms/create');
}
return $view;
}
private function processEditForm(Room $room)
{
if ($this->request->isPost()) {
$post = $this->request->getPost()->toArray();
/* here I put structure_id in $post array. */
$post['structure_id'] = $room->getStructure()->getId();
/* After this , my previous room obj is update with the data come from the
From, but the $structure entity is NULL. I don't know why. I will use the id
stores in $post['structure_id'] to fetch the Structure obj*/
$this->form->setData($post);
if (!$this->form->isValid()) {
$view = new ViewModel(array('form' => $this->form,
'title' => 'Some erros during rooms processing'));
$view->setTemplate('structures/rooms/create');
return $view;
}
$return = $this->roomService->updateRoomFromArray($room);
if ($return ) {
$this->flashMessenger()->setNamespace('rooms')->addMessage('Operation executed correctly');
return $this->redirect()->toRoute('rooms/index');
}
else {
echo "Errore durante Editing della room";
}
}
}
更新数据的服务方法 public function updateRoomFromArray(Room $ room){ / *我调用Room Entity方法来更新我的房间 / $ I_event = Room :: updateFromArray($ room); / 持久数据* / $这 - > I_mapper-> updateRoom($室); }
public function updateFromArray($room)
{
/* here I fetch the Structure's relationship my Room obj belongs to */
$structure_id = $room->getStructureId();
$structure = $this->getStructure($structure_id);
/* here I set the link*/
$room->setStructure($structure);
return $room;
}
public function updateRoom(\Structures\Entity\Room $room)
{
$this->entityManager->merge($room);
$this->entityManager->flush();
}
我想知道您对我的代码的看法。使用Doctrine2是正确的方法吗?提前谢谢
答案 0 :(得分:0)
注释的语法不正确。
您的ManyToOne关联必须具有以下简单格式:
@ManyToOne(targetEntity =“Structures \ Entity \ House”,inversedBy =“features”) @JoinColumn(name =“house_id”,referencedColumnName =“id”)
查看文档以获取更多信息: http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
希望这有帮助。
穆罕默德。