【问题标题】:Symfony join with many to manySymfony 加入多对多
【发布时间】:2015-06-30 07:31:01
【问题描述】:

我想知道如何将一个连接变成另一个连接。

我的查询生成器

return $this->createQueryBuilder("t")
->leftjoin("t.playlist","p","WITH","p.genres=:genreP")
->setParameter(":genreP",$genre)
->addSelect("p")
->getQuery()
->getResult()
;

我遇到了这个错误:[Semantical Error] line 0, col 170 near 'genres=:genreP': Error: Invalid PathExpression。需要 StateFieldPathExpression 或 SingleValuedAssociationField。

我想做什么:

我有一个 Trending 实体,它与 Playlist 实体具有 OneToOne 关系。playlist 实体与 Playlist 实体具有 ManyToMany 关系>体裁实体。

趋势实体:

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

/**
*@ORM\OneToOne(targetEntity="Song", inversedBy="trending")
*/
private $song;

/**
*@ORM\OneToOne(targetEntity="Album", inversedBy="trending")
*/
private $album;

/**
*@ORM\OneToOne(targetEntity="Playlist", inversedBy="trending")
*/
private $playlist;
}

播放列表实体

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

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

/**
* @ORM\Column(name="public", type="boolean")
*/
private $public = true;

/**
*@ORM\ManyToOne(targetEntity="user", inversedBy="playlists")
*@ORM\joinColumn(nullable=false)
*/
private $user;

/**
*@ORM\ManyToMany(targetEntity="Song", inversedBy="playlists")
*@ORM\joinColumn(nullable=false)
*/
private $songs;

/**
*@ORM\ManyToMany(targetEntity="Genre", inversedBy="playlists")
*/
private $genres;

/**
*@ORM\OneToOne(targetEntity="Image", cascade={"persist","remove","refresh"})
*/
private $image;

/**
*@ORM\ManyToMany(targetEntity="user", inversedBy="playlistLikes")
*@ORM\JoinTable(name="playlist_likes")
*/
private $likes;

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

/**
*@ORM\ManyToMany(targetEntity="user", inversedBy="playlistDislikes")
*@ORM\JoinTable(name="playlist_dislikes")
*/
private $dislikes;

/**
*@ORM\Column(name="description", type="text", nullable=true)
*/
private $description;

/**
*@ORM\ManyToMany(targetEntity="Langue", inversedBy="playlist")
*/
private $languages;

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

/**
*@ORM\OneToOne(targetEntity="Trending", mappedBy="playlist", cascade=    {"persist","remove"})
*/
private $trending;
}

趋势表

id | playlist_id | song_id | album_id
54 | 9           | null    | null

播放列表表

id | title
9  | My best

playlist_genre 表

playlist_id | genre_id
9           | 1
9           | 4

类型表

id | name
1  | Hip Hop
2  | Konpa
3  | Electronic
4  | Reggae

我想选择任一genre_id 为4 的播放列表。

谢谢。

【问题讨论】:

  • ->setParameter(":genreP",$genre) 应该是 ->setParameter("genreP",$genre)。但是我在这里无法理解实体之间的关系,您可以发布实体代码吗?此外,您为什么要实现来自趋势实体的查询?有必要吗?
  • 我刚刚编辑了我的问题。这是必要的

标签: php mysql entity-framework symfony


【解决方案1】:

你试过 CONTAINS 功能吗?

->leftjoin("t.playlist","p","WITH","p.genres CONTAINS :genreP")

编辑:如果 contains 在连接上不起作用,您可以随时在 as where 子句上尝试它

【讨论】:

  • 我尝试了 CONTAINS 功能,但我收到了这个错误,例如 CONTAINS 无法识别。你能告诉我如何尝试使用 where 子句吗?我试过->leftjoin("t.playlist","p")->addSelect("p")->where("p.genres = :g")->setParameter(":g",$genre),但我有同样的错误
  • 我打算在 where 子句上尝试 CONTAINS。或者您可以使用 MEMBER OF。它将是 ->leftjoin("t.playlist","p","WITH"," :genreP MEMBER OF p.genres");同样,我从未在联接中使用过 MEMBER OF 或 CONTAINS,因此您可以从 leftjoin 切换到 join 并尝试将它们作为 where 子句
  • CONTAINS on the join 或 where 给了我同样的错误。我已经尝试过 MEMBER OF 但是,它似乎只验证实体是否是同一个家庭,因为无论 id 是否是我需要的,它都会返回所有播放列表。我怎样才能把这个论坛设置为已解决?
  • 您可以通过单击左侧计数下方的勾号将答案标记为已回答
【解决方案2】:

抱歉这个愚蠢的问题。 我只是通过进行两次连接来解决它。

->leftjoin("t.playlist","p")
->leftjoin("p.genres","g")
->addSelect("p")
->where("g = :g")
->setParameter(":g",$genre)

这行得通。如果有人有更好的想法来优化请求,我会很感兴趣!

【讨论】:

    猜你喜欢
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多