我有一个名为foo
的实体,它与一个名为bar
的实体具有OneToMany关联,可以作为$foo->getBar()
(ArrayCollection)访问。通常调用$foo->getBar()
会触发关联bar
实体的延迟加载(如果它们最初未加入)。
如何在不触发延迟加载的情况下检查是否已加载bar
?我不需要关联的实体,如果它们最初没有加载,我不希望它们加载,我只想知道它们是否被加载。
在fooRepository
我有一个名为getFooWithBar()
的方法,它有一个连接,它将所有bars
作为ArrayCollection加载,并返回foo
所有关联的bar
getFooById()
1}}实体。但是,如果我只使用简单查询调用bar
之类的简单方法,则$foo
实体未加载连接,因此它们不包含在getBar()
中。
所以在另一个控制器中我有$ foo,我想检查public function __get($property) {
return isset($this->$property) ? $this->$property : null;
}
是否已加载关联实体,但我不想触发延迟加载。如果它没有关联的实体,我不想要它们。我只需要知道他们是否已被装载。
注意:我也不想在所有实例的实体关联上关闭延迟加载。
我把这个神奇的getter方法放在我的实体中:
getProperty()
理论上,我可以检查属性是否已设置(或者它是否仍然是默认的私有声明)。当我的实体是拥有方时,这就有效。但如果它是反面,那么$ this->属性永远不会被设置。 Doctrine做了一些奇特的事情,所以当你null
时,它会在其他地方查看数据。我想通了这个,因为当它是拥有方(它返回关联实体的代理)时,此函数有效,但当关联实体由另一个实体拥有时,它返回class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
。
答案 0 :(得分:7)
除了Carlos&#39;回答,注意重要的是,为了检查是否已加载关联,WITHOUT触发器LazyLoad,您必须使用不同的方法,具体取决于它的关联类型。 Doctrine(不幸的是)中没有记录这些内容,所以你必须查看源代码和/或使用代码。
假设您有一个具有两种不同类型关联的实体,如下所示:
$foo = {
'bar': OneToMany Association of type ArrayCollection of multiple entities,
'baz': ManyToOne Association as a Single Entity
};
正如Carlos所说,对于作为ArrayCollection的关联,您可以检查arrayCollection是否像这样初始化。如果你这样检查,并且没有加载它,它将不会触发常规的LazyLoad:
// Returns TRUE or FALSE
$initialized = $foo->getBar()->isInitialized();
但对于常规单一实体的协会来说,事情变得更加棘手。该实体不是ArrayCollection,因此它没有isInitialized()
函数。有一个__isInitialized()
函数,但这对我们的目的来说几乎毫无价值,因为如果它没有被初始化它会返回false,如果它被初始化它会产生错误(因为加载的实体没有&#39) ;有那种方法)。
// Returns False if baz entity is not loaded
// Throws an error if baz entity is loaded
$initialized = $foo->getBaz()->__isInitialized();
所以我们发现另一个要检查的属性是否可靠。代理上存在__isInitialized__
属性,这意味着未加载实体,但如果您请求该实体的属性,则它将被延迟加载。因此,如果您不想延迟加载,如果它尚未加载,您可以检查此属性是否存在。如果存在,则不加载实体。一旦实体加载,该属性就不会存在于真实实体上。
if(property_exists($entity, '__isInitialized__')) {
// If property exists, then this is a proxy value and the entity has not been loaded yet
} else {
// If the property does not exist, then the real entity has been loaded
}
答案 1 :(得分:3)
加载foo对象时,bar将是Doctrine\ORM\PersistentCollection
的实例。您可以在此集合上调用isInitialized()
方法,以确定是否已初始化。
对于ArrayCollection
$initialized = $foo->getBar()->isInitialized();
答案 2 :(得分:0)
如果你有最新版本的Doctrine,你可以在列上尝试额外的延迟加载。 更多Extra lazy associations