Doctrine 2 Symfony 2获取没有映射的外键实体

时间:2016-02-01 14:21:05

标签: php mysql symfony orm doctrine-orm

所以我对Symfony和Doctrine相当新。我想知道是否有一种方法可以问问学说外键是什么,但不必在模型中映射关系。

例如,假设您CoreBundle:Company始终存在,然后您OptionalBundle:Client将使@OneToOne映射关系扩展公司,并添加更多字段在自身。问题是,由于OptionalBundle可能不存在,我不想要从CoreBundleOptionalBundle的显式映射。

现在说用户出现并尝试删除Company(5)。如果实体已完全映射,它将使用级联删除两者,但由于捆绑包不会意识到映射关系,它最终只会删除公司 - 我想产生错误而不是级联删除。

如果这很容易实现,那么我还想进一步说一下,哪些实体(class和id)有外键我可以向用户显示数据,比如

@CoreBundle:Company(5) ->
    has @OptionalBundle:Client(3) linked, and
    has @AnotherOptionalBundle:Supplier(12) linked

我的第一直觉是为外键执行自定义INFORMATION_SCHEMA查找,但这只会给我表名...

PS 我真的不想使用任何第三方供应商,因为我喜欢尝试保持依赖关系,即使这意味着重新发明轮子

3 个答案:

答案 0 :(得分:1)

您是否考虑过将OptionalBundle所拥有的关系定义为什么?

答案 1 :(得分:1)

问题1

您可以将Client设置为1对1关系的所有者。但是,根据您的使用情况,它可能不太理想,但如果这对您有用,那么它将是最简单的解决方案,正如 ABM_Dan 所指出的那样。

除此之外,您最好的选择可能是使用Doctrine event subscribers并挂钩preDelete事件,您可以在Client之前移除关联的Company }本身被删除 - 如果级联删除真的是你想要的。

默认情况下,删除操作都在同一个Doctrine事务中,这意味着如果删除Company时出现问题,Client删除将被取消。

如果你真的想要触发错误而不是这个"手动级联"对于各种类型,也可以在Doctrine订阅者的preDelete方法中使用。

订阅者类可以驻留在您的可选包中,即使它将对与Company相关联的事件起作用。

Doctrine事件订阅者与常规Symfony事件系统是分开的。新人通常不知道它的存在,但它可以实现很多有趣的事情。

问题2

仍然在您的活动订阅者中,可以挂钩postLoad事件。这将允许您直接向Company请求数据库和加载相关实体。您可以在需要它的每个捆绑包中为Company创建一个事件订阅者。

虽然这是可能的,但我真的很想知道是否有更好的方法。使用decorators可能是更好的解决方案。我发现了一个Doctrine cookbook article

答案 2 :(得分:0)

我遇到的唯一想法是在编译器通过期间预先创建类映射,当辅助包不存在时使用一些回退类型。

在编译器传递中,检查容器是否已加载辅助包,并使用带调整路径的gson。如果找到 - 使用辅助包的实体映射,如果不是 - 将其映射为空(例如)。