【问题标题】:Doctrine Assocation Mapping Join Not Executing In ZF3在 ZF3 中未执行 Doctrine 关联映射联接
【发布时间】:2019-03-04 04:00:08
【问题描述】:

我正在为加入创建我的第一个关联映射。这也是我第一次在 pgSQL 中使用外键。

我正在使用 ZF3。我收到的错误是:

An exception occurred while executing 'SELECT p0_.reference AS reference_0, p0_.meta_keyword_reference AS meta_keyword_reference_1, p0_.add_date AS add_date_2, p0_.add_membership_reference AS add_membership_reference_3, p0_.remove_date AS remove_date_4, p0_.remove_membership_reference AS remove_membership_reference_5 FROM page_about_meta_keyword_link p0_ INNER JOIN meta_keyword m1_':
SQLSTATE[42601]: Syntax error: 7 ERROR:  syntax error at end of input LINE 1: ...page_about_meta_keyword_link p0_ INNER JOIN meta_keyword m1_

我要创建的查询是

SELECT MetaKeywords.Keyword FROM PageAboutMetaKeywordLink INNER JOIN MetaKeywords ON PageAboutMetaKeywordLink.MetaKeywordReference = MetaKeywords.Reference WHERE PageAboutMetaKeywordLink.RemoveDate IS NULL ORDER BY MetaKeywords.Keyword ASC

根据我的数据库经验,我预计它会由于缺少而产生错误

ON p0_.meta_keyword_reference = m1_reference

我不明白如何传达加入。基于documentation,我预计这是自动的。可能我理解错了。

我要加入的表是 page_about_meta_keyword_link.meta_keyword_reference ON meta_keyword.reference 。这是我第一次在 pgSQL 中创建外键。

这是 page_about_meta_keyword_link

的表结构
CREATE TABLE public.page_about_meta_keyword_link
(
  reference bigint NOT NULL DEFAULT nextval('page_about_meta_keyword_link_reference_seq'::regclass),
  meta_keyword_reference bigint,
  add_date timestamp with time zone DEFAULT now(), -- UTC
  add_membership_reference bigint,
  remove_date timestamp with time zone, -- UTC
  remove_membership_reference bigint,
  CONSTRAINT page_about_meta_keyword_link_pkey PRIMARY KEY (reference),
  CONSTRAINT page_about_meta_keyword_link_fk FOREIGN KEY (meta_keyword_reference)
  REFERENCES public.meta_keyword (reference) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT page_about_meta_keyword_link_reference_unique UNIQUE (reference)
)

这是元关键字

CREATE TABLE public.meta_keyword
(
  reference bigint NOT NULL DEFAULT nextval('meta_keyword_reference_seq'::regclass),
  keyword text,
  effective_date timestamp with time zone DEFAULT now(), -- UTC
  membership_reference bigint,
  CONSTRAINT meta_keyword_pkey PRIMARY KEY (reference),
  CONSTRAINT meta_keyword_reference_unique UNIQUE (reference)
)

这是我在服务中创建的查询;完整的服务位于here

$repository = $this->entityManager->getRepository(PageAboutMetaKeywordLink::class);
$keywords = $this->entityManager->getRepository(MetaKeyword::class);

$qb = $repository->createQueryBuilder('l');
             $qb ->join('\Application\Entity\MetaKeyword' , 'k')
                 ->expr()->isNull('l.removeDate');

return $qb->getQuery()->getResult();

我创建的关联映射是针对 meta_keyword_reference;找到完整的实体here

/**
 * @var int|null
 *
 * @ORM\ManyToOne(targetEntity="MetaKeyword")
 * @ORM\JoinColumn(name="meta_keyword_reference", referencedColumnName="reference")
 * @ORM\Column(name="meta_keyword_reference", type="bigint", nullable=true)
 */
private $metaKeywordReference;

我没有对 MetaKeywords 实体进行任何更改。找到here

总体而言,网站的各个部分将共享 meta_keywords。如果我理解正确,我试图建立的连接是多对一。

我想为其他新手留下一个很好的参考,因为他们是 Zend Framework 3 - Doctrine 的旅程。请告知我应该对这篇文章进行的编辑,使其清晰、易于理解和简洁,以便我得到我需要的帮助,并且其他人将来会从中受益。

【问题讨论】:

    标签: join zend-framework doctrine-orm doctrine zend-framework3


    【解决方案1】:

    您双重声明了一个列 (meta_keyword_reference)。查看the docs(您链接的同一页面),您在注释中犯了一个错误。删除ORM\Column 行(定义已经在JoinColumn 中)。如果您需要它可以为空(不需要),请将nullable=true 添加到JoinColumn;使用其中一个,而不是两个都使用

    /**
     * @var int|null
     *
     * @ORM\ManyToOne(targetEntity="MetaKeyword")
     * @ORM\JoinColumn(name="meta_keyword_id", referencedColumnName="id", nullable=true)
     */
    private $metaKeywordReference;
    

    不用担心声明“类型”,Doctrine 会自动将它与您引用的列匹配。此外,您应该引用主键。我假设reference不是 PK,所以我将其更改为id,将其更改为实际情况。

    接下来,我认为您也在使用 DBAL QueryBuilder 而不是 ORM QueryBuilder。

    你需要的查询是这样的:

    use Doctrine\ORM\Query\Expr\Join;
    use Doctrine\ORM\QueryBuilder;
    
    /** @var QueryBuilder $qb */
    $qb = $this->entityManager->createQueryBuilder();
    $qb->select('l')
       ->from(PageAboutMetaKeywordLink::class, 'l')
       ->join(MetaKeyword::class, 'k', Join::ON, 'l.reference = k.id') // check these property names (NOT DB COLUMNS!)
       ->where('l.removeDate is null');
    

    那里可能有一些小错误,但应该就是这样。

    【讨论】:

      猜你喜欢
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多