2014-09-29 149 views
2

我正在构建SNMP陷阱日志记录的应用程序。它有两个MySQL表格:一个带有陷阱,另一个带有我想记录的主机。Doctrine 2中的可选ManyToOne关系

陷阱表填充在外部。主持人可以通过网站进入。主机可以有一个或多个陷阱。一个陷阱可以有一台主机。

所以这是一个多对一的关系,但双方都是可选的。我如何实现这一点,因为Doctrine要求其中一个成员是主键,因此不能为空?

代码为两类:

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

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

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

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

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

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

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

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

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

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

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

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

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

    /** 
    * @ORM\ManyToOne(targetEntity="Host", inversedBy="traps") 
    * @ORM\JoinColumn(name="agentip", referencedColumnName="ip", nullable=true) 
    */ 
    protected $host; 
} 
class Host 
{ 
    /** 
    * @var string 
    * @ORM\Id 
    * @ORM\Column(name="ip", type="string", length=16) 
    */ 
    private $ip; 

    /** 
    * @ORM\Column(name="hostname", type="string", length=100) 
    */ 
    private $hostname; 

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

    /** 
    * @ORM\Column(name="importance", type="integer", length=1) 
    */ 
    private $importance; 

    /** 
    * @ORM\OneToMany(targetEntity="Trap", mappedBy="host") 
    */ 
    protected $traps; 
} 

编辑错误 的错误是,我不能删除或截断我的hosts表,这应该在我的应用成为可能,因为陷阱必须能够在没有主机的情况下存在。

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`snmptt`.`snmptt`, CONSTRAINT `FK_9BF059B998B5BE9E` FOREIGN KEY (`agentip`) REFERENCES `hosts` (`ip`)) 
+0

你的多对一关系对我来说看起来不错你提出了什么错误? – 2014-09-29 09:24:03

+0

错误是我不允许删除或截断我的主机表,这应该可以在我的应用程序中使用,因为陷阱必须能够在没有主机的情况下存在。 – 2014-09-29 09:28:44

+0

如果你试图删除这个直接续集然后是错误是正确的你不能删除父母之前,断开孩子,如果没有父母那么这是好的,如果这样先解除链接然后删除 – 2014-09-29 09:35:54

回答

0

作为回答发表评论为相信是合适的答案;

“如果你试图删除这个直续集则是错误的是正确的,你不能删除父之前取消链接的孩子,如果没有父母,那么这是好的,如果这样断开链接首先然后删除”

+0

我可以在不清除'trap'记录中的'agentip'字段的情况下执行此操作吗? – 2014-09-29 09:46:56

+0

不幸的是,如果关系确实存在,则这是外地主机上的一个foriegn关键约束。你是通过mysql还是使用原则来做到这一点?如果您删除了主机,您是否希望陷阱仍然存在? – 2014-09-29 09:50:33

+0

陷阱和主机需要存在而不需要彼此。可能有主机没有陷阱(尚未),或没有链接到主机的陷阱。之后,这些'孤儿'陷阱将显示在网站的不同区域,但在服务器上收到陷阱的程序无法识别陷阱是否有主机,因此它将它们放在同一个表中数据库。 – 2014-09-29 09:54:23