2015-02-10 65 views
3

我的實體(產品)與另一個實體(公司)具有單向多關係deletedByCompanies假設相關實體不存在選擇實體

我希望選擇所有未被特定公司刪除的產品。這就是所有沒有通過那麼多關係連接起來的產品。

嘗試:

$this->em->getRepository(Product::class)->createQueryBuilder('t') 
->leftJoin('t.deletedByCompanies', 'deletedCompany') 
->andWhere('deletedCompany.id not in (:companyId)') 
->setParameter('companyId', [$companyId]); 

但這根本不返回任何東西。 架構是相當straghtforward:

Product: 
    id: int PK 

Company: 
    id: int PK 

DeletedProducts 
    product_id: int FK 
    company_id: int FK 

實體定義產品類:

/** 
* @var Company[] 
* @ORM\ManyToMany(targetEntity="Company", indexBy="id") 
* @ORM\JoinTable(name="DeletedProducts") 
*/ 
protected $deletedByCompanies; 
+0

*「我希望選擇所有未被特定公司刪除的產品。」*。您的意思是隻有那些未被該公司刪除的**刪除**產品?或者所有的產品,包括那些根本沒有被刪除的產品? – axiac 2015-02-12 16:18:50

+0

顯示錶格結構(表格名稱和ID字段名稱)。 – axiac 2015-02-12 16:19:47

+0

只有公司的NOT DELETED產品。 – 2015-02-12 17:11:23

回答

3

我認爲你可以用deleby表上的NOT EXISTS子句解決你的問題。

在SQL方言:

SELECT * FROM product p WHERE NOT EXISTS 
(SELECT * FROM DeletedProducts d WHERE p.id=d.product_id AND company_id = 2); 

在Doctrine2 DQL,我們沒有實體DeletedProducts,所以我們必須做更多的東西,如:

$qb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('t') 
    ->Join('t.deletedByCompanies', 'deletedCompany') 
    ->andWhere('deletedCompany.id in (:companyId)') 
    ->andWhere("p=t"); 

$mainQb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('p'); 
$mainQb->where($mainQb->expr()->not($mainQb->expr()->exists($qb->getDQL()))); 
$mainQb->setParameter('companyId', [$companyId]); 

var_dump($mainQb->getQuery()->getSql()); 
$res =$mainQb->getQuery()->execute(); 

讓我知道如果我不明白你的問題。

希望得到這個幫助

+0

如果您想重複使用此代碼,請創建一個自定義存儲庫類... http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes – 2015-02-18 14:47:50

+0

謝謝@GuilhermeViebig,當然!此方法必須駐留在自定義存儲庫方法中!順便說一句,這只是一個DNL風格的查詢轉換的例子,所以我沒有涉及這方面,我希望邁克能做一點重構,並照顧你的意見!再次感謝! – Matteo 2015-02-18 14:50:15

2

我不熟悉的學說,但我想幫助一些SQL知識。下面的查詢應該做你想要什麼:

SELECT DISTINCT Product.* FROM Product 
LEFT JOIN DeletedProducts on product_id = product.id 
WHERE product_id IS NULL OR product_id != 
    ALL(SELECT product_id FROM DeletedProducts WHERE company_id = 2) 

一些解釋...

DISTINCT: Nessacary關鍵字,以防止冗餘。如果左連接被刪除,同一產品可能會出現多次。 DISTINCT消除了這些重複項。

WHERE的product_id IS NULL:左連接也將列出未在「DeletedProducts」 - 表相關的任何一家公司的產品。由於沒有關係,所以字段product_idcompany_idNULL

或product_id!= ALL([...]):現在我們已經獲得了未被任何公司刪除的產品,我們還需要那些未被特定公司刪除的產品。因此,我們使用以及選擇某個公司的所有刪除產品(例如,如代碼示例中的公司id = 2)的子查詢。由於我們希望擁有未刪除的產品,因此我們必須使用「!=」 - 運算符。

我希望這會有所幫助。現在,您需要在Doctrine中「翻譯」查詢用法。

+0

好吧,現在必須做。我做了一個低級別的查詢來獲得我想選擇的記錄ID。然後,純粹的學說選擇基於簡單的「ID in(...)」標準。謝謝。 – 2015-02-13 08:45:00