Php 条令2,实体内部查询

Php 条令2,实体内部查询,php,filter,doctrine-orm,doctrine,Php,Filter,Doctrine Orm,Doctrine,如何在实体中执行查询 namespace Entities\Members; /** * @Entity(repositoryClass="\Entities\Member\MembersRepository") * @Table(name="Members") * @HasLifecycleCallbacks */ class Members extends \Entities\AbstractEntity { /** * @Id @Column(name="id"

如何在实体中执行查询

namespace Entities\Members;

/**
 * @Entity(repositoryClass="\Entities\Member\MembersRepository")
 * @Table(name="Members")
 * @HasLifecycleCallbacks
 */
class Members extends \Entities\AbstractEntity
{
    /**
     * @Id @Column(name="id", type="bigint",length=15)
     * @GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /** 
     * @Column(name="userid", type="bigint", length=26, nullable=true) 
     */
    protected $userid;

    /** 
     * @Column(name="fname", type="string", length=255,nullable=true) 
     */
    protected $fname;

    /**
     *  @OneToMany(targetEntity="\Entities\Users\Wall", mappedBy="entry", cascade={"persist"}) 
     */
    protected $commententries;

    public function __construct()
    {
        $this->commententries = new \Doctrine\Common\Collections\ArrayCollection();
    }
}
示例我希望在这个实体中有一个名为:
filter()
我希望能够过滤
commentrients
集合。它应该返回具有特定条件的集合,例如
id=1
。基本上,它应该过滤从连接查询接收的数据

比如说:

$this->commententries->findBy(array('id' => 1));
<?php
// create a new service, injecting the entitymanager.  if you later wanted 
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);

$favoriteCommentaries = $svc->getFavoriteCommentaries($member);

但是很明显,这是行不通的。

你的问题真的很难理解,请试着在将来如何组织你的问题。例如,您说“返回相同的结果”,但说“过滤器”,这可能意味着任何事情。你想使用相同的结果集(你到底为什么会选择这样做),只使用array\u filter或array\u walk来过滤结果,还是你真的想使用条件连接?这是难以置信的模棱两可

无论如何。。回答(在阅读问题4次后)


一般来说,你不应该这样做

根据经验,实体不应该知道entitymanager(直接或通过某种中介对象)

这样做的原因主要是可测试性,但根据我的经验,它有助于以其他方式组织事情

我将通过设计一个服务类来处理查找。您的控制器(或其他什么)会像这样驱动它:

$this->commententries->findBy(array('id' => 1));
<?php
// create a new service, injecting the entitymanager.  if you later wanted 
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);

$favoriteCommentaries = $svc->getFavoriteCommentaries($member);

您的ArrayCollection已经实现了一个filter()方法,您需要传递一个闭包以使它在实体中工作(这里是commentEntries)

(未测试)

请注意,这种方法将迭代并快速加载您的所有评论,因此在用户有很多评论的情况下,这可能是一个很大的瓶颈

在大多数情况下,您希望使用自定义存储库,在其中可以放置此类逻辑

正如timdev所建议的,您可以创建一个MemberService,它将通过了解EntityManager来包装这样的调用


将实体与边界层分离是对原则1的一大改进,您不应该违反该规则。

我同意“timdev”。您不应该在entities类中定义查询。我定义服务类的方法支持实体是存储库类。例如:用户(实体--YourBundle/entity/User.php)将拥有UserRepository(服务类--YourBundle/Repository/UserRepository.php)。你的“过滤器”方法应该在这里。您只需要在实体类中映射此服务类。在控制器中,您始终可以通过其存储库访问“过滤器”。在“使用自定义存储库进行查询”中有非常详细的记录

您不应该在实体中编写查询,但应该使用存储库来编写查询。这一点在条令文件中也有解释。它将允许您在中心位置构建自定义查询,并保持实体定义的整洁

使用条件筛选集合:

但是,如果您想在集合中使用
get
方法进行筛选,您可以使用
标准。您可以在条令文档中阅读如何使用标准。要按您希望的方式进行筛选,请执行以下操作:

$this->commententries->findBy(array('id' => 1));
<?php
// create a new service, injecting the entitymanager.  if you later wanted 
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);

$favoriteCommentaries = $svc->getFavoriteCommentaries($member);
在实体类的顶部声明
条件

use Doctrine\Common\Collections\Criteria
getCommentEntries
方法中,使用类进行筛选:

public function getCommentEntries()
{
    $criteria = Criteria::create()
        ->where(Criteria::expr()->eq('id', 1));

    $filteredCommentEntries = $this->commententries->matching($criteria);

    return $filteredCommentEntries;
}

你能在实体类中使用数组过滤器吗?我试过:数组过滤器($a,数组(“成员”,“入口过滤器”));但找不到类。如果要将getResult()作为模式数组返回,则可以。这就像跨过任何阵列一样。->getQuery()->getResult(2)就可以了。在php闭包中,必须用括号括起变量,例如,使用($idsToFilter),您可以使用自定义存储库来完成此操作,该存储库已使用@Entity(repositoryClass=“\Entities\Member\MembersRepository”)定义。检查我下面的答案:@deanjase我在很长时间后再次来到这里,并注意到之前不清楚您是否想要筛选您的收藏。我更新了我的答案,因为在你的集合
get
方法中进行过滤是绝对可能的。虽然答案很旧,但我在过滤集合文档中发现了这样一个小注释:“你可以将集合片段的访问移到实体的专用方法中。例如,Group#getTodaysBirthdayUsers()。这显然使实体可以访问EntityManager。这是否违反了规则?@aftAbnaved将此方法添加到实体时,您不会公开EntityManager。在本例中,他们首先获取
$group
来收集
$userCollection
。在您的组实体中,您只需执行
$this->getUsers()在自定义getter中,然后添加条件逻辑。