如果User
有BlogPost
个Event
,则BlogPost
属于Venue
,其属性为**
* @ORM\Entity()
* @ORM\Table(name="User")
*/
class User {
...
/**
* @ORM\OneToMany(targetEntity="BlogPost",mappedBy="User")
* @ORM\JoinColumn(...)
*/
protected $BlogPosts;
...
}
/**
* @ORM\Entity()
* @ORM\Table(name="BlogPost")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(...)
* @ORM\DiscriminatorMap({...})
* ...
*/
class BlogPost {
...
/**
* @ORM\ManyToOne(targetEntity="User",inversedBy="BlogPosts")
* @ORM\JoinColumn(...)
*/
protected $User
...
}
/**
* @ORM\Entity()
* @ORM\Table(name="Event")
*/
class Event extends BlogPost {
...
/**
* @ORM\ManyToOne(targetEntity="Venue")
* @ORM\JoinColumn(...)
*/
protected $Venue;
...
}
/**
* @ORM\Entity()
* @ORM\Table(name="Venue")
*/
class Venue {
...
}
。
我有以下实体类:
$qb = $em->createQueryBuilder();
$qb
->select('User,'BlogPost,Venue')
->from('User','User')
->join('User.BlogPosts','BlogPost','WITH','BlogPost INSTANCE OF :Event')
->join('BlogPost.Venue','Venue')
->setParameter('Event',$em->getClassMetadata('Event'));
我现在想要构建一个查询来获取给定的用户事件并急切地加载事件场所。我最接近的是:
Error: Class BlogPost has no association named Venue
这给了我一个相当可预测的错误:
Venue
删除对Event
的引用我会让所有用户Event
都很好但是我将不得不依赖延迟加载来获取{{1}的其余部分}的属性。
我看到了我在Events
中映射User
的建议:
class User {
...
/**
* @ORM\OneToMany(targetEntity="BlogPost",mappedBy="User")
* @ORM\JoinColumn(name="UserID", referenceColumnName="UserID")
*/
protected $BlogPosts;
/**
* @ORM\OneToMany(targetEntity="Event",mappedBy="User")
* @ORM\JoinColumn(name="UserID", referenceColumnName="UserID")
*/
protected $Events;
...
}
尝试此操作时,生成的SQL会尝试执行以下操作:
SELECT * FROM User
JOIN Event ON User.id = Event.user_id
JOIN BlogPost ON BlogPost.id = Event.blog_post_id
其中user_id
是BlogPost
而不是Event
的列,因此出现以下错误:
Invalid column name 'user_id'
我应该如何映射Class Table Inherited reference? 有没有办法实现我所描述的急切加载?
我知道我从类,它们的映射和生成的SQL中省略了一些细节。如果某些细节有助于深入了解,请大声说。
修改
这与Single Table Inheritance (STI) with a ManyToOne relationship不同,因为它类表继承而不是单表继承。另外,我对子类的属性的细节感兴趣,想象一下,如果在该示例中,Video
有额外的引用。
答案 0 :(得分:0)
我找到了一种可以做我想要的方式,但我确信必须有更好的方法。
首先编写本机查询:
$em->getConnection()->prepare()
这可以直接通过$em->createNativeQuery($sql,$rsm)
运行,也可以更好地使用ResultSetMapping然后通过$rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($em);
$rsm->addRootEntityFromClassMetadata('User','user');
$rsm->addIndexBy('user','id');
$rsm->addJoinedEntityResult('event','event','user','BlogPosts');
$rsm->addJoinedEntityResult('venue','venue','event','Venue');
$rsm->addFieldResult(); // add all of the fields you are interested in
$query = $this->get_manager()->createNativeQuery($sql,$rsm);
$query->setParameter(1, $user_id);
return $query->getResult($hydration_mode);
QueryBuilder
这似乎无法通过 var uploadDate = new Date();
完成,但据我所知,这是实现这一目标的唯一方法。我很乐意以其他方式表现出来。