Soru Karşılaştırmalı ölçütlerle bir findBy yöntemi nasıl kullanılır?


Karşılaştırmalı kriterleri kullanarak (sadece kesin ölçütleri değil) bir "sihir bulucu" findBy yöntemini kullanmam gerekir. Başka bir deyişle, böyle bir şey yapmalıyım:

$result = $purchases_repository->findBy(array("prize" => ">200"));

böylece ödülün 200'ün üzerinde olduğu tüm alımları alacağım.


58
2018-02-09 10:01


Menşei


Çirkin gerçek şu ki: Tamamen büyük, okunamaz ve sezgisel olmayan düşük düzeyli bir sorgu oluşturmazsanız, Symfony'de bu mümkün değildir. Ve unutmayın, bu sadece süper temel bir şey, daha karmaşık sorgularla nasıl başa çıkacağınızı hayal edin! Symfony'yi KULLANMAMANIZI herkese tavsiye ederim! - Sliq
@Sliq neden burada Symfony? Doctrine \ ORM paketinden geliyor .... Herkesin konuşmadan önce bir şey anlamasını öneriyorum ^^ - Thomas Decaux
Eğer doktrin ya da symfony'nin sizin bir şey olmadığını düşünüyorsanız, projeniz için yanlış bir çerçeve seçtiniz. Bu çerçeveler birçok proje için harika çalışıyor. - mask8


Cevaplar:


Bu, kullanarak bir örnektir Expr () Sınıfı - Birkaç gün önce buna ihtiyacım vardı ve tam sözdizimi ve kullanım şekli nedir diye bana biraz zaman ayırdı:

/**
 * fetches Products that are more expansive than the given price
 * 
 * @param int $price
 * @return array
 */
public function findProductsExpensiveThan($price)
{
  $em = $this->getEntityManager();
  $qb = $em->createQueryBuilder();

  $q  = $qb->select(array('p'))
           ->from('YourProductBundle:Product', 'p')
           ->where(
             $qb->expr()->gt('p.price', $price)
           )
           ->orderBy('p.price', 'DESC')
           ->getQuery();

  return $q->getResult();
}

28
2018-02-09 12:58



Tam olarak gerekmediğinde DQL kullanmaktan kaçının, mantığınızı daha çok ORM'ye bağlı hale getirin. - Ocramius
@Ocramius Symfony gibi bir şeye benzemeyen DQL'den kaçınmak mümkün değil -> findBy (X) -> nerede (Y> 7) basitçe mümkün değil: / - Sliq
@Sliq bu bir doktrin davranışıdır ve mutlaka symfony ile ilgisi yoktur. - con
@Sliq biraz daha çerçeveler denedikten sonra, Symfony'nin bu kadar berbat olmadığını anlayacaksınız. - Marián Zeke Šedaj


Sınıf Doctrine\ORM\EntityRepository uygular Doctrine\Common\Collections\Selectable API.

Selectable Arabirim çok esnek ve oldukça yenidir, ancak ORM veya ODM veya tamamen ayrı sorunlardan bağımsız olarak, hem depolarda hem de tek koleksiyon koleksiyonlarında karşılaştırmaları ve daha karmaşık kriterleri kolayca ele almanızı sağlar.

Bu sadece Doctrine ORM’de olduğu gibi bir karşılaştırma kriteri olacaktır. 2.3.2:

$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->gt('prize', 200));

$result = $entityRepository->matching($criteria);

Bu API’nın en büyük avantajı, burada bir çeşit strateji modeli uygulamanızdır ve depolar, koleksiyonlar, tembel koleksiyonlar ve her yerde çalışır. Selectable API uygulandı.

Bu, depolarınız için yazdığınız düzinelerce özel yöntemden kurtulmanızı sağlar ( findOneBySomethingWithParticularRuleBunun yerine, her biri bu belirli filtrelerden birini temsil eden kendi ölçüt sınıflarınızı yazmaya odaklanın.


155
2018-02-09 16:20



çok çok güzel bir yaklaşım. Thanx Ocramius! - kieste
Tasarım desenlerine iyi referans! - VladRia
Beni çok fazla beladan kurtardın. Bunu gördüğümde bir sarıcı yazmaya başlamak üzereydim :). - zozo
Not: Doktrin ile symfony 2.8.11 kullanıyorum ve - belki sadece orada - bu "Ölçüt :: expr () -> gt ()" değil, "$ ölçüt-> expr () -> gt ()". - Select0r
Bu statik bir yöntem: github.com/doctrine/collections/blob/...  Ayrıca: Symfony DEĞİL Doktrin. Doktrin isimleri ve sürümleri ile referans doktrin şeyler: -P - Ocramius


Ya da DQL ya da Sorgu oluşturucu. Örneğin. Satın aldığınızdaEntityRepository böyle bir şey yapabilirsin:

$q = $this->createQueryBuilder('p')
          ->where('p.prize > :purchasePrize')
          ->setParameter('purchasePrize', 200)
          ->getQuery();

$q->getResult();

Daha karmaşık senaryolar için bir göz atın Expr () sınıfı.


6
2018-02-09 10:18



Kesinlikle gerekli olmayan DQL kullanmaktan kaçının. Sizi ORM'ye özel API'ye kilitler ve gerçekten tekrar kullanılamaz. DQL'nin gerekli olduğu bazı durumlar var, ama bu bunlardan biri değil. - Ocramius
QueryBuilder'ı kullanmanız sizi aynı şekilde doktrine nasıl kilitlemez? - NDM


Symfony belgeleri şimdi bunu nasıl yapacağınızı açıkça göstermektedir:

$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
    'SELECT p
    FROM AppBundle:Product p
    WHERE p.price > :price
    ORDER BY p.price ASC'
)->setParameter('price', '19.99');    
$products = $query->getResult();

itibaren http://symfony.com/doc/2.8/book/doctrine.html#querying-for-objects-with-dql


3
2018-04-18 16:33





$criteria = new \Doctrine\Common\Collections\Criteria();
    $criteria->where($criteria->expr()->gt('id', 'id'))
        ->setMaxResults(1)
        ->orderBy(array("id" => $criteria::DESC));

$results = $articlesRepo->matching($criteria);

1
2017-10-03 13:23



Bu benim için çalışmıyor, gör stackoverflow.com/questions/49450970/... - Olli D-Metz